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

浏览:29日期:2023-03-23

问题描述

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

#pragma onceclass 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;}

一起运行报错:c++链接错误,始终想不通

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

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

问题解答

回答1:

是因为你的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 onceint 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只被包含了一次。

回答2:

都两个答案给你说了问题不在头文件引入,你怎么还死钻? 问题都说给你了。

int A::x = 1; 这句应该写在CPP,一般数据成员的初始化都放到构造函数里做。

1.cpp

void A(){ x = 1;}

相关文章: