为什么允许具有本身具有不完整类型静态成员的类?

Kyl*_*rry 2 c++

我很难理解为什么类可以具有自身的不完整类型静态成员。

例如在下面的代码中。为什么允许在类A内拥有自身的不完整类型静态成员,但是当类类型B的全局静态变量是不完整类型时却出现错误?

class B {
public:
    B(int a) {
    }
};

static B test2; //error


class A {

public:
    static A test; //accepted

    A(int d) {
    }
};
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释在后台给全局静态变量带来错误的原因是什么,为什么A类内部的静态变量会被接受?

use*_*301 6

在这里混淆了几个不同的问题

static B test2; //error
Run Code Online (Sandbox Code Playgroud)

失败,因为B的构造函数需要尚未提供的参数,private因此无法在类外部进行访问。改正那些,B很高兴。

class B {
public: // added for outside access to constructor
    B(int a) {
        printf("%d\n", a);
    }
};

static B test2{1}; // added arguments
Run Code Online (Sandbox Code Playgroud)

至于Astatic成员不是类实例的一部分,因此编译器不需要它是完整的。它不占用任何空间,目前还没有用于任何东西。这只是一个声明。您可以在不使编译器感到不安的情况下声明各种内容(只要声明的语法良好即可)。当您尝试使用没有定义的内容时会遇到麻烦。

例:

void testfunc(const A &)
{

}

int main(){
    testfunc(A::test);
}
Run Code Online (Sandbox Code Playgroud)

在链接器上失败,因为A::test从未定义。如果您尝试使用

class A {

public:

    static A test{1}; // let's try to define it inline!
    int a;
    int b;
    int c;

    A(int d, int e) : a(d), b(e), c(15) {

    }

    A(int d) :A(d, 10) {
        printf("%d %d %d", a, b, c);
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,编译器非常在意报告该类不完整。我们必须将定义移到完整的类之外

class A {

public:

    static A test; //declared
    int a;
    int b;
    int c;

    A(int d, int e) : a(d), b(e), c(15) {

    }

    A(int d) :A(d, 10) {
        printf("%d %d %d", a, b, c);
    }
};
A A::test{1}; // defined
Run Code Online (Sandbox Code Playgroud)

现在

void testfunc(const A &)
{

}

int main(){
    testfunc(A::test);
}
Run Code Online (Sandbox Code Playgroud)

将编译并链接。

有关static会员照顾和喂养的文件