我是初学程序员,我想知道......
我需要为游戏中的对象提供唯一的ID
所以我认为我定义了一个包含全局id的全局类,当我调用一个对象的构造函数时它会递增,而在调用该对象的析构函数时它会递减它。
对于每个构造函数调用都会有相应的析构函数吗?
class id_holder{
private:
int id_count;
public:
id_holder() {id_count = 0 ; std::cout<< "unique_id: I'm constructed"<<std::endl;}
~id_holder(){std::cout<<"unique_id: I'm destructed"<<std::endl;}
void increment_id(){id_count ++;};
void decrement_id(){id_count --;};
int get_id() {return id_count;};
};
class BaseObject {
protected:
void increment_id();
void decrement_id();
public:
virtual ~BaseObject(){decrement_id();}
BaseObject();
BaseObject(V2 pos, ObjectType idobj, double s, Color col);
};
BaseObject::BaseObject(){
//stuff
increment_id();
unique_id = bObj_id_counter.get_id();
}
BaseObject::BaseObject(V2 pos, ObjectType idobj, double s, Color col){
//stuff
increment_id();
unique_id = bObj_id_counter.get_id();
}
void BaseObject::increment_id(){
bObj_id_counter.increment_id();
}
void BaseObject::decrement_id(){
bObj_id_counter.decrement_id();
}
方面问题...是否可以比较对象的内存地址(这应该是一个唯一的id),而不是使用id_holder?
答案 0 :(得分:4)
对于每个构造函数调用都会有一个 相应的析构函数?
是的,除非您使用operator new分配对象并且不销毁它们,或者您的应用程序异常终止。
除非您同时使用它,否则您的解决方案应该可以正常运行。如果你这样做,你应该提供对该全局对象的独占访问权,但我不认为是这种情况。
是否可以比较内存地址(这应该是唯一的 足够的id)而不是使用id_holder
你可以这样做,每个对象都有一个唯一的内存地址。这是一种肮脏的解决方案,取决于您的目标。
答案 1 :(得分:3)
不,这不一定是真的。在每个表现良好的程序中,每个构造函数调用都有一个析构函数调用。但是,例如,如果使用new
构造的对象不是delete
d,则不会有析构函数调用。
此外,在您的示例中,您没有实现复制构造函数,这意味着您可能会考虑比构造函数调用更多的析构函数调用。
此外,您也没有实现赋值运算符。如果使用默认对象,则分配给的对象将与分配的对象具有相同的unique_id
。 (假设unique_id
是BaseObject
的成员,你没有在你的代码片段中声明。)这样会使你的unique_id
非常“独特”。 ; - )
答案 2 :(得分:1)
这通常称为“引用计数”,它具有广泛的用途。是的,这是可能的,但你的工作还不能正常工作。
id
,然后使用curiously recurring template pattern确保此id
仅为全局特定类型。然后,每种类型在构建期间都会获得全局id
的副本。increment_id()
类调用decrement_id()
和id_holder
,因此没有理由在BaseObject
构造函数/析构函数中再次调用它们。这是一个相对优雅的解决方案,允许您对给定ID的项目执行常量查找等操作。例如:
template <class T>
class counter
{
static size_t global_id_;
size_t id_;
public:
counter() : id_(global_id_++) {}
counter(const counter&) : id_(global_id++) {}
~counter() {}
counter& operator=(const counter&)
{
// left as an exercise for the reader
// as what to do in this case is highly
// dependent upon the application
}
};
class counted_object : public counter<counted_object>
{
// stuff
};
现在您可以保存一个存储在向量中的counted_objects
查找表,以便快速查找:
std::vector<counted_object*> lookup;
counted_object* o416 = lookup[416];
答案 3 :(得分:0)
是的,它是,是的,你可以比较地址。唯一的问题是,如果您有内存泄漏,并且对象不会被删除。
每个对象都有一个唯一的地址。即使您创建一个空类或结构,它的大小也不会为零(通过语言设计)。在处理多个线程时,从构造函数传递this
引用时要小心,因为您的对象可能没有完全构造。
编辑:你可以利用这个来发现内存泄漏。假设您在程序退出时删除了您创建的每个对象(如清理方法),只需查看是否还有任何对象。
EDIT2:Here's一篇关于C ++中对象计数的非常好的文章
答案 4 :(得分:0)
是的,每个类都会有一个析构函数,如果你没有提供默认值,编译器会给你一个默认值。看C++ default destructor