C++ 外部链接
C++ extern linking
我想尝试使用外部链接和不完整的类型声明并编写了这个示例:
Source.cpp:
//Source.cpp
class A {
public:
int a=10;
};
A* var1 = new A();
void printA(A* arg)
{
cout << arg->a << endl;
}
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;
}
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;
}
在第一次调用 printA()
后,“10”如我所料打印出来。但是为什么在第二次调用printA()
和printB()
之后还打印了“10”呢?
您的程序以一种不需要诊断的方式违反了单一定义规则,因此是病式的。您程序中的两个翻译单元都定义了一个名为 A
的 class 并带有外部链接,但定义不同。允许编译器和链接器假定它们是相同的 class。您的程序没有 "correct" 输出。
欢迎来到违反单一定义规则的精彩世界。您有两个 classes,都在文件范围内定义,共享一个名称。
因为 classes 默认有外部链接,你对同一个 class 有两个定义,它们彼此不一致。这会使您的程序格式错误,compiler/linker 可以抱怨,或者继续做奇怪的事情。
另一方面,强制 class 内部链接的方法是在未命名的命名空间中声明它:
namespace {
class A {
public:
int a=10;
};
}
由于未命名的名称空间对于每个翻译单元都是唯一的,因此您实际上将有 两个 单独的 class 定义。需要注意的是,您不能再从翻译单元外部向它们声明 extern
变量。
我想尝试使用外部链接和不完整的类型声明并编写了这个示例:
Source.cpp:
//Source.cpp
class A {
public:
int a=10;
};
A* var1 = new A();
void printA(A* arg)
{
cout << arg->a << endl;
}
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;
}
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;
}
在第一次调用 printA()
后,“10”如我所料打印出来。但是为什么在第二次调用printA()
和printB()
之后还打印了“10”呢?
您的程序以一种不需要诊断的方式违反了单一定义规则,因此是病式的。您程序中的两个翻译单元都定义了一个名为 A
的 class 并带有外部链接,但定义不同。允许编译器和链接器假定它们是相同的 class。您的程序没有 "correct" 输出。
欢迎来到违反单一定义规则的精彩世界。您有两个 classes,都在文件范围内定义,共享一个名称。
因为 classes 默认有外部链接,你对同一个 class 有两个定义,它们彼此不一致。这会使您的程序格式错误,compiler/linker 可以抱怨,或者继续做奇怪的事情。
另一方面,强制 class 内部链接的方法是在未命名的命名空间中声明它:
namespace {
class A {
public:
int a=10;
};
}
由于未命名的名称空间对于每个翻译单元都是唯一的,因此您实际上将有 两个 单独的 class 定义。需要注意的是,您不能再从翻译单元外部向它们声明 extern
变量。