Подскажите пожалуйста, как правильно сделать уникальный идентификатор для экземпляров класса, чтобы он сохранялся и при наследовании?
Пытаюсь делать так:
class a
{
public:
a(void) {
id0++;
id = id0;
}
static int id0;
int id;
}
int a::id0 = 0;
class b : public a
{
}
a ex1; // в ex1 id равен 1
b ex2; // в ex2 id равен 0 ?? почему так и как сделать чтобы был равен 2 ?
Этого не может быть. В приведенном коде ошибки нет.
#include <iostream>
struct a
{
public:
a(void) {
id0++;
id = id0;
}
static int id0;
int id;
};
int a::id0 = 0;
struct b : public a
{
};
int main() {
a ex1;
b ex2;
std::cout << "A: " << a.id << "B: " << b.id << "\n";
}
A: 1B: 2
Ищи ошибку где-то еще. Например, у тебя не покрыт конструктор копирования.
Здравствуйте, Vamp, Вы писали:
V>Этого не может быть. В приведенном коде ошибки нет.
V>Ищи ошибку где-то еще. Например, у тебя не покрыт конструктор копирования.
Здравствуйте, pivcorp, Вы писали:
P>Здравствуйте, Force_Majeure, Вы писали:
F_M>>ActionObject::ActionObject(void)
P>ActionObject::ActionObject(void):Object() P>{ P>//... P>}
Да, так Id присваивается!
Будь другом, разъясни пожалуйста, как это работает? Я думал, что через двоеточие можно только давать значения по умолчанию параметрам в конструкторе, если сам конструктор с параметрами.
В следующих наследниках от ActionObject я должен буду всю цепочку классов развернуть через двоеточие или хватит только непосредственного предка?
Здравствуйте, Force_Majeure, Вы писали:
F_M>Здравствуйте, pivcorp, Вы писали:
P>>Здравствуйте, Force_Majeure, Вы писали:
F_M>>>ActionObject::ActionObject(void)
P>>ActionObject::ActionObject(void):Object() P>>{ P>>//... P>>}
F_M>Будь другом, разъясни пожалуйста, как это работает? Я думал, что через двоеточие можно только давать значения по умолчанию параметрам в конструкторе, если сам конструктор с параметрами.
Это называется список инициализации. В коде который ты показал сначала как якобы ошибочный
был конструктор автоматически сгенеренный компилятором, так как твоего конструктора не было.
Автоматически компилятор сгенерил код который предка инициализирует.
В реальном коде явно прописан конструктор, а значит что ты написал то и будет, т.е. если
нет инициализации она и не произойдет.
В этом конструкторе ты не инициализировал предка. Соответственно конструктор предка не вызывался.
F_M>В следующих наследниках от ActionObject я должен буду всю цепочку классов развернуть через двоеточие или хватит только непосредственного предка?
Если конструктор предка инициализирует своего предка достаточно инициализировать одного.
Т.е.
class A0
{
public:
A0()
{
//some code
}
};
class A1 : public A0
{
public:
A1():A0(){}
};
class A2 : public A1
{
public:
A2():A1(){}
};
A3 a; //some code вызовется здесь
P>Это называется список инициализации. В коде который ты показал сначала как якобы ошибочный P>был конструктор автоматически сгенеренный компилятором, так как твоего конструктора не было. P>Автоматически компилятор сгенерил код который предка инициализирует. P>В реальном коде явно прописан конструктор, а значит что ты написал то и будет, т.е. если P>нет инициализации она и не произойдет. P>В этом конструкторе ты не инициализировал предка. Соответственно конструктор предка не вызывался.
Неправда. Дефолтный конструктор вызывается всегда. Инициализация нужна, чтобы вызвать конструктор, отличный от дефолтного. И в твоем примере списки инициализации не нужны.
Здравствуйте, Vamp, Вы писали:
P>>Это называется список инициализации. В коде который ты показал сначала как якобы ошибочный P>>был конструктор автоматически сгенеренный компилятором, так как твоего конструктора не было. P>>Автоматически компилятор сгенерил код который предка инициализирует. P>>В реальном коде явно прописан конструктор, а значит что ты написал то и будет, т.е. если P>>нет инициализации она и не произойдет. P>>В этом конструкторе ты не инициализировал предка. Соответственно конструктор предка не вызывался. V>Неправда. Дефолтный конструктор вызывается всегда. Инициализация нужна, чтобы вызвать конструктор, отличный от дефолтного. И в твоем примере списки инициализации не нужны.
Допустим я ошибся, вполне вероятно.
Вопрос, а Object::Object(void) в коде не дефолтный конструктор?
Тогда интересно Ваше объяснение почему не работало и вдруг
заработало после добавления конструктора предка в список инициализации
P>Вопрос, а Object::Object(void) в коде не дефолтный конструктор?
Дефолтный. P>Тогда интересно Ваше объяснение почему не работало и вдруг P>заработало после добавления конструктора предка в список инициализации
Не знаю. Думаю, что дело там совсем в другом.
Здравствуйте, Vamp, Вы писали:
P>>Вопрос, а Object::Object(void) в коде не дефолтный конструктор? V>Дефолтный. P>>Тогда интересно Ваше объяснение почему не работало и вдруг P>>заработало после добавления конструктора предка в список инициализации V>Не знаю. Думаю, что дело там совсем в другом.
Поскольку правы Вы (я проверил), а код он привел, интересно все же узнать
почему изменение которое предложил я сработало.
Здравствуйте, AlexCrush, Вы писали:
AC>Так что в чем то другом проблема. AC>Несмотря на то, что предложенное pivcorp решение как-то вам помогло, советую все же разобраться в проблеме глубже.
(Проверим телепатию)
А нет ли там случайно виртуального наследования?
class A {}
class B1 : public virtual A {}
class B2 : public virtual A {}
class C : public B1, public B2 {}
> int main() { > > a ex1; > b ex2; > > std::cout << "A: " << a.id << "B: " << b.id << "\n"; > }
Наверное ex1.id и ex2.id. И сорри за offtop, может подскажешь, почему
под linux данный пример успешно компилируется вот так:
c++ static_var.cpp -o static_var
но выдает кучу ошибок при такой компиляции:
demas@arch ~/sources/study/cpp/oop $ gcc static_var.cpp -o static_var
/tmp/ccfaAbgX.o: In function `main':
static_var.cpp.text+0x36): undefined reference to `std::cout'
static_var.cpp.text+0x3b): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char,
std::char_traits<char> >&, char const*)'
static_var.cpp.text+0x47): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >::operator<<(int)'
static_var.cpp.text+0x57): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char,
std::char_traits<char> >&, char const*)'
static_var.cpp.text+0x63): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >::operator<<(int)'
static_var.cpp.text+0x73): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char,
std::char_traits<char> >&, char const*)'
/tmp/ccfaAbgX.o: In function
`__static_initialization_and_destruction_0(int, int)':
static_var.cpp.text+0xa2): undefined reference to
`std::ios_base::Init::Init()'
static_var.cpp.text+0xa7): undefined reference to
`std::ios_base::Init::~Init()'
/tmp/ccfaAbgX.o.eh_frame+0x12): undefined reference to
`__gxx_personality_v0'
collect2: выполнение ld завершилось с кодом возврата 1
Posted via RSDN NNTP Server 2.1 beta
Re[3]: как сделать уникальный идентификатор?
От:
Аноним
Дата:
31.07.09 05:50
Оценка:
Здравствуйте, DemAS, Вы писали: DAS>под linux данный пример успешно компилируется вот так: DAS>c++ static_var.cpp -o static_var DAS>но выдает кучу ошибок при такой компиляции: DAS>
DAS>demas@arch ~/sources/study/cpp/oop $ gcc static_var.cpp -o static_var
DAS>/tmp/ccfaAbgX.o: In function `main':
DAS>static_var.cpp.text+0x36): undefined reference to `std::cout'
Потому что надо линковаться с плюсовой стандартной библиотекой. Вариантов два:
1) вызывать g++ — он сам разберется, где находится нужная ему libstdc++
2) указывать явно: gcc static_var.cpp -o static_var -lstdc++
Здравствуйте, WeCom, Вы писали:
WC>Здравствуйте, AlexCrush, Вы писали:
AC>>Так что в чем то другом проблема. AC>>Несмотря на то, что предложенное pivcorp решение как-то вам помогло, советую все же разобраться в проблеме глубже.
WC>(Проверим телепатию) WC>А нет ли там случайно виртуального наследования?
WC>class A {} WC>class B1 : public virtual A {} WC>class B2 : public virtual A {} WC>class C : public B1, public B2 {}
Нет, ни виртуального (я, честно, и не знал о таком), ни множественного наследования нет.