考虑以下代码:
#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 C和LINE B都试图使用类的静态对象,分别是int Wilma::i
和Wilma 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类的什么地方?