C ++ extern链接

时间:2017-10-15 20:38:07

标签: 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;
}

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”?

2 个答案:

答案 0 :(得分:5)

您的程序违反了One Definition Rule,不需要诊断,因此格式错误。程序中的两个翻译单元都定义了一个带有外部链接的名为A的类,但定义不同。允许编译器和链接器假定它们是同一个类。没有&#34;正确&#34;你节目的输出。

答案 1 :(得分:5)

欢迎来到One Definition Rule违规的精彩世界。您有两个类,都在文件范围内定义,共享一个名称。

由于类默认情况下具有外部链接,因此您对同一个类有两个定义,彼此不同意。这会使您的程序格式不正确,编译器/链接器可能会抱怨,或者只是继续并做一些奇怪的事情。

另一方面,强制类的内部链接的方法是在未命名的命名空间中声明它:

namespace {

    class A {
    public: 
       int a=10;
    };

}

由于未命名的命名空间对于每个翻译单元都是唯一的,因此实际上您将具有两个单独的类定义。需要注意的是,您无法再从翻译单元外部向他们声明extern变量。