在C++中创建对象时,如何将对象指针推到向量
How to push object pointer to vector when object is created in C++?
我正试图在创建对象的同时将对象指针添加到向量中。目前我已经在对象的构造函数中完成了这项工作,但现在我听说这是一种错误的方式,因为对象并没有完全在这一点上创建。
MyObject类构造函数:
// MyObject constructor
MyObject::MyObject() {
// add object to vector of all objects
MyObjectManager::Instance()->objects.push_back(this);
}
MyObject只是对象的基类。我还有MyRectangle类,它是从MyObject继承的,所以当我创建新的MyRectanger时,就会调用MyObject构造函数,并将我新创建的对象推送到MyObjectManager的向量中。
MyObjectManager是一个单例类,它保存所有对象的列表,并非常频繁地调用它们的虚拟Draw函数。这就是问题所在吗?MyObjectManager可能会在对象完全创建之前调用对象的Draw函数?
我可以制作一个单独的方法来将对象添加到向量中。类似这样的东西:
MyObject::Create() {
// add object to vector of all objects
MyObjectManager::Instance()->objects.push_back(this);
}
但我必须这样使用它:
MyRectangle *rect = new MyRectangle(0.5, 0.5, 0.1, 0.1);
rect->Create();
我只想能够简单地通过如下构造函数实例化新对象:
MyRectangle *rect = new MyRectangle(0.5, 0.5, 0.1, 0.1);
您可以在构造函数中做到这一点,不是吗?
MyRectangle::MyRectangle(const float& a, const float& b, const float& c, const float& d) {
this->Create();
}
如果您有特殊的MyObjectManager
类,您也可以将其用作对象的工厂。要阐明它,请考虑代码:
struct MyObjectManager {
template <typename T, typename... Args>
T * createObject(Args... args) {
T *ret = new T(args...);
m_objects.push_back(ret);
return ret;
}
std::vector<MyObjects *> m_objects;
};
对象创建:
MyRectangle *rect = MyObjectManager::Instance()->createObject<MyRectangle>(1.0, 2.0, 3.0, 4.0);
也许您可以考虑使用工厂模式:
MyRectangle * factoryMyRectangle(float x, float y, float w, float h)
{
MyRectangle *rect = new MyRectangle(x,y,w,h);
rect->Create();
return rect;
}
您可以拨打:
MyRectangle *rect = factoryMyRectangle(0.5, 0.5, 0.1, 0.1);
很大程度上取决于上下文。如果push_back
是最后一个构造函数中的指令,并且没有派生类,应该没有问题。同样,如果你在单线程环境(并且由于您不执行任何操作锁定,您必须是),并且派生类不执行任何操作通过矢量中的指针,没有问题。你是允许具有指向尚未完全构造的对象的指针,只要你不尝试使用他们指向的实际对象。
这可能是一个问题的一种情况是,如果你在多线程环境中的基类构造函数。如果你将指针推到未完全构造为yes的对象,以及然后另一个线程接管,在矢量,并试图使用它,你就有麻烦了。有处理此问题的各种技术:最常见的可能是使用工厂函数来构造所有对象,并具有工厂函数做push_back
,在构造函数完成。所以你永远不会打电话给new MyRectangle(...)
工厂功能之外。(通常,工厂函数将是一个静态成员,构造函数将私人的,所以你可以保证这一点。)
请注意,如果您确实使用了工厂函数,您可能会希望将new
的结果保留在智能指针中,直到push_back
已完成:
std::unique_ptr<MyRectangle> tmp( new MyRectangle(...) );
MyObjectManager::Instance()->objects.push_back( tmp.get() );
tmp.reset()
如果您可以保证在对象完全构建之前不会对其进行访问,而只对其进行存储,那么像您那样使用this
指针应该不会有问题。如果有另一个线程处理绘制更新,例如,轮询管理器类中的所有对象并定期调用它们的draw
函数,那么这种保证就失效了。
看看这个问题和这个问题,了解更多信息。
- 对象指针在c++中是如何工作的
- C++ 对象指针数组的复制构造函数
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 正确初始化和销毁对象指针的C++数组?
- 如何深度复制链表对象指针
- 对象指针 c++ 的全局向量错误
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- 静态对象指针
- 正在将对象指针数组初始化为NULL
- 如何使用条件表达式返回对象指针?
- std::flush可以用于将对象指针转换为其封闭数组指针吗
- 使用C对象指针构建PyObject*
- 如何在使用对象指针时访问成员函数
- 静态强制转换允许转换对象指针,但不允许转换整数
- C++ abort() 在函数内的抽象类对象指针调用上
- 指向函数的对象指针
- 访问指向对象指针向量的指针的第一个元素?
- 如何将对象/指针正确存储到 Qlist 中
- 对象指针打印结果以相反的顺序进行