явное определение статического члена - PullRequest
4 голосов
/ 12 июля 2011

Рассмотрим этот код:

#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 явно определяет статическое int a класса Wilma (закомментировано, чтобы вызвать ошибку компоновщика) и без которого компоновщик выдает неопределенную ошибку ссылки (потому что Wilma:: я на самом деле используется, если я его не использую, там нет ошибок компоновщика.)

То же самое должно быть верно для статического Wilma wilma_ из класса Fred, то есть оно должно быть явно определено aswell..потому что этотакже используется в коде в строке B. Но это не так, нет ошибок компоновщика для Fred :: wilma_, если он не был явно определен.Зачем?Протестировано на gcc 4.5.2

РЕДАКТИРОВАТЬ: У меня почему-то есть еще одно сомнение по этому поводу ...

LINE C и LINE B оба пытаются использовать статические объекты класса, int Wilma::i и Wilma Fred::wilma_ соответственно.Но только определение для int Wilma::i является обязательным?

Почему не Wilma Fred::wilma_; является обязательным?

Я понимаю ответ, что строка B не используется.но то же самое можно сказать и о линии C тоже ??

Ответы [ 2 ]

3 голосов
/ 13 июля 2011

Wilma не имеет нестатических полей.Fred::wilma_=w; ничего не делает.

edit

Если нет нестатических элементов - нет копии.По сути, назначение было неактивным и могло быть просто оптимизировано компилятором, а компоновщик его никогда не видел.Добавление нестатического члена сделало копию фактической операцией, которая ссылалась на статическую переменную, поэтому компилятор не смог ее оптимизировать, и компоновщик это увидел.

1 голос
/ 13 июля 2011

Вы объявили static int i; в Wilma, но никогда не определяли его. Таким образом, добавляя обратно в строку A , это приведет к тому, что Wilma :: i будет определена , на что жалуется компилятор. Таким образом, вы должны определить где-то вне класса, а не внутри main.

Наконец, классы Фреда и Вильмы по существу пусты (кроме ctor и статического члена класса). Между ними нечего копировать.

Редактировать: Исходя из комментариев к @littleadv, у вас должен быть идентичный класс, если вы собираетесь выполнить копию. Если вы поместите int j в класс Wilma, но не в класс Fred, тогда он не будет работать, потому что куда он должен поместить j в класс Fred?

...