搜尋

首頁  >  問答  >  主體

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 天前397

全部回覆(2)我來回復

  • 伊谢尔伦

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

    是因為你的int A::x分別在1.cpp和main.cpp被定義了兩次,連結器不知道哪個才是正確的。

    你可以把int A::x = 1; 放到1.cpp中去。

    pragma once的作用並不是防止多次編譯,而是多次包含,不管你寫不寫pragma once,每個包含1.h的cpp檔都會拷貝一份1.h到它的編譯單元中進行編譯,pragma once的作用是在多次(直接或間接)包含同一個頭檔時不重複包含。

    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可以正常編譯而不發生int a 的重定義,因為a.h只被包含了一次。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 15:39:39

    都兩個答案給你說了問題不在頭文件引入,你怎麼還死鑽? 問題都說給你了。


    int A::x = 1; 這句話應該寫在CPP,一般資料成員的初始化都放到建構函式裡做。

    1.cpp

    void A()
    {
        x = 1;
    }

    回覆
    0
  • 取消回覆