4

考虑这段代码:

#include<iostream>
using namespace std;
class Wilma
{
    public:
        static int i;
        Wilma()
        {
            cout<<"\nWilma ctor\n";
            cout<<"\ni::"<<i<<"\n";
        }
};
class Fred
{
    public:
        Fred()
        {
            cout<<"\nFred ctor\n";

        }
        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 类的静态 Wilma wilma_ 也应如此,即它也应显式定义..因为它也在 B 行的代码中使用。但事实并非如此,如果 Fred::wilma_ 没有链接器错误没有明确定义。为什么?在 gcc 4.5.2 上测试

编辑: 我不知何故对此有另一个疑问......

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

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

我理解B 行是无操作的答案。但是C线也可以这样说??

4

2 回答 2

3

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

编辑

如果没有非静态成员 - 没有副本。基本上,分配是一个空操作,可能只是被编译器优化了,链接器从来没有看到它。添加非静态成员使副本成为引用静态变量的实际操作,因此编译器无法优化它并且链接器看到了它。

于 2011-07-12T20:04:10.190 回答
1

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

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

编辑:根据对@littleadv 的评论,如果要执行副本,则必须具有相同的课程。如果你在 Wilma 类中放了一个 int j 而在 Fred 类中什么都没有,那么它将不起作用,因为它应该将 j 放在 Fred 类的什么位置?

于 2011-07-12T20:15:00.910 回答