как сделать уникальный идентификатор?
От: Force_Majeure Россия  
Дата: 30.07.09 15:37
Оценка:
Подскажите пожалуйста, как правильно сделать уникальный идентификатор для экземпляров класса, чтобы он сохранялся и при наследовании?
Пытаюсь делать так:

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 ?
Re: как сделать уникальный идентификатор?
От: Ovl Россия  
Дата: 30.07.09 15:44
Оценка:
приведенный код идентичен тому, где проявляется ошибка?
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[2]: как сделать уникальный идентификатор?
От: Force_Majeure Россия  
Дата: 30.07.09 15:51
Оценка:
Здравствуйте, Ovl, Вы писали:

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


Упрощено передает то что у меня. Могу скопировать полные классы, но это будет большой код.
Re[3]: как сделать уникальный идентификатор?
От: Force_Majeure Россия  
Дата: 30.07.09 16:04
Оценка:
Здравствуйте, Force_Majeure, Вы писали:

F_M>Здравствуйте, Ovl, Вы писали:


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


вот куски кода целиком


// Object.h

class Object
{
private:
protected:
    LPDIRECT3DDEVICE9 pD3DDevice;
    FrustumPiramide* pFrustum;
public:    
    Object(void);
    virtual ~Object(void);
    LogFile* Log;
    std::string BasePath;

    int Id;
    static int AllId;

    // Функции
    bool SetRenderDevice(LPDIRECT3DDEVICE9 Device);
    bool SetFrustum(FrustumPiramide* Frustum);
    FrustumPiramide* GetFrustum();
};

//Object.cpp

#include "StdAfx.h"
#include "Object.h"
int Object::AllId = 0;
Object::Object(void)
{
pD3DDevice = NULL;
pFrustum = NULL;
Log = NULL;
char Path[200];
GetCurrentDirectory(200,Path);
BasePath = std::string(Path)+"\\Data\\";

AllId++;
//MessageBox(NULL,(Common::IntToStr(AllId)).c_str(),"",NULL);
Id = AllId;

}
Object::~Object(void)
{
}

// ActionObject.h

class ActionObject :
    public Object
{
private:
protected:
    struct Action {
        virtual ~Action(void){}
        char Id;
        char Priority;
    };
    std::vector<Action*> Actions;

public:
    ActionObject(void);
    virtual ~ActionObject(void);

    virtual bool SetAction(unsigned int Act);        // Установка действия для выполнения
    virtual bool RemoveAction(unsigned int Act);    // Удаление действия для выполнения
    virtual bool RunAction();                        // Выполнение действия
};

// ActionObject.cpp

#include "StdAfx.h"
#include "ActionObject.h"
ActionObject::ActionObject(void)
{
}
ActionObject::~ActionObject(void)
{
for(std::vector<Action*>::iterator i=Actions.begin();i!=Actions.end();++i) {
    delete *i;
}
Actions.clear();
}

// В программе вызываю

Object a;
Log->Add("a "+Common::IntToStr((a.Id)));
ActionObject c;
Log->Add("c "+Common::IntToStr((c.Id)));
Object b;
Log->Add("b "+Common::IntToStr((b.Id)));


//Получаю в логе запись:
a 8
c 0
b 10
Re: как сделать уникальный идентификатор?
От: Vamp Россия  
Дата: 30.07.09 16:06
Оценка:
Этого не может быть. В приведенном коде ошибки нет.


#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


Ищи ошибку где-то еще. Например, у тебя не покрыт конструктор копирования.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: как сделать уникальный идентификатор?
От: pivcorp Россия  
Дата: 30.07.09 16:15
Оценка: 2 (1)
Здравствуйте, Force_Majeure, Вы писали:

F_M>ActionObject::ActionObject(void)


ActionObject::ActionObject(void):Object()
{
//...
}
Re[2]: как сделать уникальный идентификатор?
От: Force_Majeure Россия  
Дата: 30.07.09 16:16
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Этого не может быть. В приведенном коде ошибки нет.


V>Ищи ошибку где-то еще. Например, у тебя не покрыт конструктор копирования.


Я вот и сам мучаюсь Я сюда http://www.rsdn.ru/forum/cpp/3487631.1.aspx
Автор: Force_Majeure
Дата: 30.07.09
скинул куски кода — все вроде правильно, но не работает
Поясни, что значит "не покрыт конструктор копирования" ?
Re[4]: как сделать уникальный идентификатор?
От: Ovl Россия  
Дата: 30.07.09 16:19
Оценка:
код верный и работает. ищите в другом месте — переполнение буфера, расстрел памяти, банальное обнуление переменной
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[5]: как сделать уникальный идентификатор?
От: Force_Majeure Россия  
Дата: 30.07.09 16:26
Оценка:
Здравствуйте, pivcorp, Вы писали:

P>Здравствуйте, Force_Majeure, Вы писали:


F_M>>ActionObject::ActionObject(void)


P>ActionObject::ActionObject(void):Object()

P>{
P>//...
P>}

Да, так Id присваивается!
Будь другом, разъясни пожалуйста, как это работает? Я думал, что через двоеточие можно только давать значения по умолчанию параметрам в конструкторе, если сам конструктор с параметрами.
В следующих наследниках от ActionObject я должен буду всю цепочку классов развернуть через двоеточие или хватит только непосредственного предка?
Re[6]: как сделать уникальный идентификатор?
От: pivcorp Россия  
Дата: 30.07.09 16:38
Оценка:
Здравствуйте, 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 вызовется здесь
Re[7]: как сделать уникальный идентификатор?
От: pivcorp Россия  
Дата: 30.07.09 16:40
Оценка:
P>A3 a; //some code вызовется здесь

Помарка вместо A3 читать A2
Re[7]: как сделать уникальный идентификатор?
От: Vamp Россия  
Дата: 30.07.09 16:46
Оценка:
P>Это называется список инициализации. В коде который ты показал сначала как якобы ошибочный
P>был конструктор автоматически сгенеренный компилятором, так как твоего конструктора не было.
P>Автоматически компилятор сгенерил код который предка инициализирует.
P>В реальном коде явно прописан конструктор, а значит что ты написал то и будет, т.е. если
P>нет инициализации она и не произойдет.
P>В этом конструкторе ты не инициализировал предка. Соответственно конструктор предка не вызывался.
Неправда. Дефолтный конструктор вызывается всегда. Инициализация нужна, чтобы вызвать конструктор, отличный от дефолтного. И в твоем примере списки инициализации не нужны.
Да здравствует мыло душистое и веревка пушистая.
Re[8]: как сделать уникальный идентификатор?
От: pivcorp Россия  
Дата: 30.07.09 16:52
Оценка:
Здравствуйте, Vamp, Вы писали:

P>>Это называется список инициализации. В коде который ты показал сначала как якобы ошибочный

P>>был конструктор автоматически сгенеренный компилятором, так как твоего конструктора не было.
P>>Автоматически компилятор сгенерил код который предка инициализирует.
P>>В реальном коде явно прописан конструктор, а значит что ты написал то и будет, т.е. если
P>>нет инициализации она и не произойдет.
P>>В этом конструкторе ты не инициализировал предка. Соответственно конструктор предка не вызывался.
V>Неправда. Дефолтный конструктор вызывается всегда. Инициализация нужна, чтобы вызвать конструктор, отличный от дефолтного. И в твоем примере списки инициализации не нужны.

Допустим я ошибся, вполне вероятно.
Вопрос, а Object::Object(void) в коде не дефолтный конструктор?
Тогда интересно Ваше объяснение почему не работало и вдруг
заработало после добавления конструктора предка в список инициализации
Re[9]: как сделать уникальный идентификатор?
От: Vamp Россия  
Дата: 30.07.09 16:56
Оценка:
P>Вопрос, а Object::Object(void) в коде не дефолтный конструктор?
Дефолтный.
P>Тогда интересно Ваше объяснение почему не работало и вдруг
P>заработало после добавления конструктора предка в список инициализации
Не знаю. Думаю, что дело там совсем в другом.
Да здравствует мыло душистое и веревка пушистая.
Re[10]: как сделать уникальный идентификатор?
От: pivcorp Россия  
Дата: 30.07.09 17:00
Оценка:
Здравствуйте, Vamp, Вы писали:

P>>Вопрос, а Object::Object(void) в коде не дефолтный конструктор?

V>Дефолтный.
P>>Тогда интересно Ваше объяснение почему не работало и вдруг
P>>заработало после добавления конструктора предка в список инициализации
V>Не знаю. Думаю, что дело там совсем в другом.

Поскольку правы Вы (я проверил), а код он привел, интересно все же узнать
почему изменение которое предложил я сработало.
Re[4]: как сделать уникальный идентификатор?
От: AlexCrush Россия  
Дата: 31.07.09 03:12
Оценка:
Здравствуйте, Force_Majeure, Вы писали:

F_M>вот куски кода целиком


Взял код, скопировал, определил неизвестные типы как void, заменил вывод в лог на принтф, получаю вывод:
1
2
3


Так что в чем то другом проблема.
Несмотря на то, что предложенное pivcorp решение как-то вам помогло, советую все же разобраться в проблеме глубже.
Re[5]: как сделать уникальный идентификатор?
От: WeCom Беларусь  
Дата: 31.07.09 04:02
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>Так что в чем то другом проблема.

AC>Несмотря на то, что предложенное pivcorp решение как-то вам помогло, советую все же разобраться в проблеме глубже.

(Проверим телепатию)
А нет ли там случайно виртуального наследования?

class A {}
class B1 : public virtual A {}
class B2 : public virtual A {}
class C : public B1, public B2 {}
Re[2]: как сделать уникальный идентификатор?
От: DemAS http://demas.me
Дата: 31.07.09 05:36
Оценка:
> 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++
Re[6]: как сделать уникальный идентификатор?
От: Force_Majeure Россия  
Дата: 31.07.09 06:14
Оценка:
Здравствуйте, 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 {}


Нет, ни виртуального (я, честно, и не знал о таком), ни множественного наследования нет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.