静态成员显式定义



考虑以下代码:

#include<iostream>
using namespace std;
class Wilma
{
    public:
        static int i;
        Wilma()
        {
            cout<<"nWilma ctorn";
            cout<<"ni::"<<i<<"n";
        }
};
class Fred
{
    public:
        Fred()
        {
            cout<<"nFred ctorn";
        }
        static Wilma wilma_;
};
int Wilma::i=44;//------------- LINE A
int main()
{
    int a=0;
    Wilma::i=a;//---------- LINE C
    Wilma w;
    Fred::wilma_=w;//---------- LINE B
}

这里的行A显式地定义了Wilma类的静态int A。(注释掉会导致链接器错误)如果没有它,链接器会给出未定义的引用错误。(因为Wilma::i实际上正在使用,如果我不使用它,没有链接器错误。)

对于Fred类i的静态Wilma wilma_也是如此。它也应该显式定义,因为它也在B行代码中使用。但事实并非如此,Fred::wilma_如果没有显式定义,则不会出现链接器错误。为什么?

编辑:

我又对这件事产生了怀疑。

LINE CLINE B都试图使用类的静态对象,分别是int Wilma::iWilma Fred::wilma_。但是只有int Wilma::i的定义是强制性的吗?

为什么Wilma Fred::wilma_;不是强制性的?

我理解的答案,行B是一个无操作。但是对于行C也可以这么说??

Wilma没有非静态字段。Fred::wilma_=w;不做任何事情。

编辑

如果没有非静态成员,则没有复制。基本上,赋值是无操作的,可能只是被编译器优化了,而链接器从来没有看到它。添加非静态成员使复制成为引用静态变量的实际操作,因此编译器无法将其优化出来,而链接器会看到它。

您在Wilma中声明了static int i;,但从未定义它。因此,通过在 A行添加,它将导致Wilma::i被定义为,这就是编译器抱怨的问题。所以你必须在类之外的某个地方定义,而不是在main中。

最后,Fred和Wilma类本质上是空的(除了一个actor和静态类成员)。他们之间没有什么可复制的

编辑:根据@littleadv的评论,如果你要执行复制,你必须有一个相同的类。如果你在Wilma类中放了一个int j但在Fred类中什么都没有,那么它就不能工作了因为它应该把j放在Fred类的什么地方?

最新更新