Nik*_*ita 3 c++ extern incomplete-type
我想尝试外部链接和不完整的类型声明,并写了这个例子:
Source.cpp:
//Source.cpp
class A {
public:
int a=10;
};
A* var1 = new A();
void printA(A* arg)
{
cout << arg->a << endl;
}
Run Code Online (Sandbox Code Playgroud)
Source1.cpp:
//Source1.cpp
class A
{
public:
int b = 20;
int c = 30;
};
A* var2 = new A();
void printB(A* a)
{
std::cout << a->b;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中:
//main.cpp
class A;
extern A* var1;
extern A* var2;
int main()
{
void printA(A*);
void printB(A*);
printA(var1); //Prints 10
printA(var2); //Prints 10
printB(var2); //Prints 10
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一次打电话printA()"10"之后就像我预期的那样打印出来.但是,为什么"10"也是第二个电话后,印刷printA()和printB()?
您的程序违反了One Definition Rule,不需要诊断,因此格式错误.程序中的两个翻译单元都定义了一个以A外部链接命名的类,但定义不同.允许编译器和链接器假定它们是同一个类.您的程序没有"正确"的输出.
欢迎来到One Definition Rule违规的精彩世界.您有两个类,都在文件范围定义,共享一个名称.
由于类默认情况下具有外部链接,因此对同一个类有两个定义,这两个定义彼此不一致.这会使你的程序格式不正确,编译器/链接器可以抱怨,或者只是继续并做一些奇怪的事情.
另一方面,强制类的内部链接的方法是在未命名的命名空间中声明它:
namespace {
class A {
public:
int a=10;
};
}
Run Code Online (Sandbox Code Playgroud)
由于未命名的命名空间对于每个翻译单元都是唯一的,因此实际上您将拥有两个单独的类定义.需要注意的是,您无法再extern从翻译单元外部向它们声明变量.