【问题标题】:static member explicit definition静态成员显式定义
【发布时间】:2011-07-12 19:58:09
【问题描述】:

考虑这段代码:

#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::iWilma Fred::wilma_ 类的静态对象。 但是只有int Wilma::i 的定义是强制性的吗?

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

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

【问题讨论】:

    标签: c++ gcc linker static-linking static-initialization


    【解决方案1】:

    Wilma 没有非静态字段。 Fred::wilma_=w; 什么都不做。

    编辑

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

    【讨论】:

    • 很好..我添加了int j;到 Wilma .. 并且链接器错误现在出现了.. 但我没有明白这一点以及 Fred::wilma_=w;什么都没做??..感谢您的快速响应。
    • @ashishsony - 为答案添加了解释。
    • @ashishsony:错误在哪里?请相应地编辑您的问题。您是否尝试将 int j 分配给班级中的某些内容?这是不允许的。
    • @littleadv .. 只是为了延长对话,如果在采访中问这个问题.. 那么应该回答什么,因为很难猜测编译器将如何优化.. 尤其是在这种情况下优化或不优化最终会导致无错误或错误。
    • @ashishsony - 我认为无论优化如何,原始代码(使用全静态 Welma)都不会以错误结尾。如果我是面试官,我在这里给出的答案对我来说是非常满意的。好吧,毕竟我给了它:-)
    【解决方案2】:

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

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

    编辑:根据@littleadv 的 cmets,如果要执行副本,则必须具有相同的类。如果你在 Wilma 类中放了一个 int j 而在 Fred 类中什么都没有,那么它就行不通了,因为它应该把 j 放在 Fred 类的什么位置?

    【讨论】:

    • 我的问题不是关于静态 int i 而是静态 Wilma wilma_
    • @ashishsony:首先很难阅读您的问题。不过,我在第二段中回答了。
    • 天哪!我认为您从其他意义上考虑了这个问题..我将 int j 添加到 Wilma,然后我将临时 Wilma 复制到静态 Wilma wilma_(Fred).. 没有问题将 int j 放入 Fred。
    猜你喜欢
    • 2021-09-11
    • 2014-02-17
    • 1970-01-01
    • 2014-06-11
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多