LINUX.ORG.RU

Пара вопросов по статическим полям класса[c++][study]

 ,


0

1

Есть абстрактный класс:

class A{
public:
virtual int Init()=0;

protected:
static int _a;
static int _b;
}

class B: public A{
public:
int Init()
  {
   return 0;
  }
}

class C: public A{
public:
int Init()
  {
   return 0;
  }
}
Теперь вопросы:
1)Являются ли переменные _a и _b общими для всех переменных класса B и C.
2)Как правильно проинициализировать переменные _a и _b (единожды).
3)Думаю возникнут еще вопросы помере поступления ответов.
Извиняюсь за кривоватость вопросов.
Спасибо за внимание!

★★★★★

Являются ли переменные _a и _b общими для всех переменных класса B и C.

да

Как правильно проинициализировать переменные _a и _b (единожды).

class A{
static int _a;
static int _b;
}

int A::_a = 0;
int A::_b = 0;

Думаю возникнут еще вопросы помере поступления ответов.

;)

s0L
()
Ответ на: комментарий от AST-PM-105

Иногда нападает неймоверный тупак... и тогда само написание вопроса как правило помогает :).. Ну а если вопрос написан, то почему бы не запостить :)

Jetty ★★★★★
()

Переменные доступны во всех классах.

Варианты инициализации.

int A::Init()
{
    _a = 0;
    _b = 1;
}

int B::Init()
{
    A::Init();
    //more specific code
}

int C::Init()
{
   _a = 1;
   _b = 2;
}

Таким образом в наследниках есть возможность либо воспользоваться стандартной инициализацией, либо использовать инициализацию предка.

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

Вообще лучше все действия по инициализации выполнять в конструкторе. Очень редко, когда классу действительно необходим метод Init();

trex6 ★★★★★
()
Ответ на: комментарий от trex6

>> А развернутый комментарий? Почему лопух?

2)Как правильно проинициализировать переменные _a и _b (единожды).

(единожды).

//и.о. К.О.

gandjubas
()
Ответ на: комментарий от trex6

>А развернутый комментарий? Почему лопух?

печатать лень, дофига писать придется, потому что бы бреда насочинял. ну раз так просишь, вот:

Таким образом в наследниках есть возможность либо воспользоваться стандартной инициализацией, либо использовать инициализацию предка.

это че такое? что за стандартная инициализация и инициализация предка?

вызов виртуальной функции в конструкторе

это здесь к чему?

Вообще лучше все действия по инициализации выполнять в конструкторе

в конструкторе никогда и нигде не выполняется инициализация (если не считать «список инициализации» написанный через двоеточие, но даже это неприменимо к статическим членам)

и какой вообще смысл в полиморфизме если речь идет о статических членах?

способ инициализации единственный и был написан тут http://www.linux.org.ru/jump-message.jsp?msgid=6597904&cid=6597953

s0L
()
Ответ на: комментарий от trex6

статический член класса, это самый обыкновенная глобальная статическая переменная, просто находится в пространстве имен класса.

s0L
()
Ответ на: комментарий от s0L

Что-то я совсем не внимательно пост ТС прочитал. Не увидел, что переменные статические.
Действительно лопух.

trex6 ★★★★★
()
Ответ на: комментарий от s0L

Спасибо за объяснение, как и ожидалось возник вопрос :)
Есть вот такой вот код:

class A {
public:
    virtual int init() = 0;
protected:
    static int _a;
    static int _b;
};

class B : public A {
public:
    int init() {
        _a = 1;
        _b = 22;
    }
};

int main(int argc, char** argv) {
    A **a = new A*[4];
    a[0] = new B;
    a[1] = new B;

    a[0]->init();
    return 0;
}
И вот часть лога компиляции
g++     -o dist/Debug/GNU-Linux-x86/cppapplication_2 build/Debug/GNU-Linux-x86/main.o  
build/Debug/GNU-Linux-x86/main.o: In function `B::init()':
/home/deylix/NetBeansProjects/CppApplication_2/main.cpp:27: undefined reference to `A::_a'
/home/deylix/NetBeansProjects/CppApplication_2/main.cpp:28: undefined reference to `A::_b'
build/Debug/GNU-Linux-x86/main.o: In function `C::init()':
/home/deylix/NetBeansProjects/CppApplication_2/main.cpp:35: undefined reference to `A::_a'
/home/deylix/NetBeansProjects/CppApplication_2/main.cpp:35: undefined reference to `A::_a'
/home/deylix/NetBeansProjects/CppApplication_2/main.cpp:36: undefined reference to `A::_b'
/home/deylix/NetBeansProjects/CppApplication_2/main.cpp:36: undefined reference to `A::_b'
collect2: выполнение ld завершилось с кодом возврата 1
gmake[2]: *** [dist/Debug/GNU-Linux-x86/cppapplication_2] Ошибка 1

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

Для обращения к статическим переменным (и методам) класса вне этого класса надо их явно объявить дополнительно за пределом этого класса.

То есть в вашем случае надо явно сделать:

int A::_a;
int A::_b;

Вне классов A и B.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

Странно, а статический метод, объявленный в классе A не вызвал такой же ошибки, хотя я обратился к нему из класса B, не объявив его отдельно, вне классов A и B.
Хотя эта ошибка возникает, если статическая функция только объявлена в теле класса A.

deterok ★★★★★
() автор топика
Ответ на: комментарий от s0L

А как быть со статическим методе, почему он не вызывает той же ошибки, если его тело находится в определение класса?

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

>почему он не вызывает той же ошибки, если его тело находится в определение класса

по той же причине, почему в .h-никах нельзя переменные обьявлять без extern. переменная статическая, и она должна существовать в одном экземпляре, соответствено конструкцию int A::a = 0 надо помещать в .cpp файл, а не .h файл

s0L
()
Ответ на: комментарий от s0L

разумеется, это все будет справедливо, когда .h-ник включается в несколько cpp файлов, но сопсно они для этого и придуманы

s0L
()
Ответ на: комментарий от s0L

Заработало, спасибо огромное!

deterok ★★★★★
() автор топика

школота
язык С++ изучать нужно по книгам извесных авторов
а не по форума с вопросами «а КАГ?»

anonymous
()
Ответ на: комментарий от anonymous

Не все люди задающие простые вопросы являются школотой, все приходит с опытом, не так ли?

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

причем здесь опыт?
если все то о чем вы спрашиваете на форуме, есть в учебнике по С++

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.