search

Home  >  Q&A  >  body text

c++链接错误,始终想不通

------------------- 文件 1.h -----------------------------------

#pragma once
class A
{
public:
    static int x;

public:
    void func();
};

int A::x = 1;

-------------------- 文件 1.cpp -----------------------

#include "1.h"

void A::func()
{
    ;
}

-------------------- 文件 main.cpp -----------------------

#include<iostream>
#include"1.h"

int main()
{
    A a;

    return 0;
}

一起运行报错:

int A::x = 1;是应该放在cpp里,但是放在.h里的话,#pragma once防止头文件被二次编译,怎么还会报错呢,我的理解是如果去掉#pragma once它才会报这样的错,但是事实却是这样,我不知道这是为什么?或者我对#pragma once的理解有误?(PS:不要讨论#ifndef...#define...#endif#pragma once的区别,重点不是这个)

我的想法是二次编译(网上博文看来的)这个说法是不是错的,#pragma once到底是为了防止头文件被二次啥啥呢?

天蓬老师天蓬老师2772 days ago395

reply all(2)I'll reply

  • 伊谢尔伦

    伊谢尔伦2017-04-17 15:39:39

    It’s because your int A::x is defined twice in 1.cpp and main.cpp respectively, and the linker doesn’t know which one is correct.

    You can put int A::x = 1; into 1.cpp.

    The function of pragma once is not to prevent multiple compilations, but to include multiple times. Regardless of whether you write pragma once or not, each cpp file containing 1.h will copy a copy of 1.h to its compilation unit. When compiling, the function of pragma once is not to include the same header file multiple times (directly or indirectly).

    a.h

    #pragma once
    int a = 0;

    main.cpp

    #include<iostream>
    #include "a.h"
    #include "a.h"
    #include "a.h"
    #include "a.h"
    #include "a.h"
    #include "a.h"
    using namespace std;
    
    int main()
    {
        cout << a << endl;
        return 0;
    }

    main.cpp can be compiled normally without the redefinition of int a, because a.h is only included once.

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 15:39:39

    Both answers told you that the problem is not introduced in the header file, so why are you still trying to figure it out? I’ve told you all the problems.


    int A::x = 1; This sentence should be written in CPP. Generally, the initialization of data members is done in the constructor.

    1.cpp

    void A()
    {
        x = 1;
    }

    reply
    0
  • Cancelreply