我正在尝试将派生类存储在没有对象切片的向量中。我有 一天中的大部分时间都在努力寻找并且没有想出如何使它发挥作用。 我读过的解决方案建议存储指向派生对象的指针 实际的对象。我无法让它工作,但我想添加这些对象 以某种方式导向向量,这将导致对象超出范围之前 向量超出范围。所以,我认为这种解决方案不会起作用 无论如何。另一个解决方案建议将基类抽象,但事实并非如此 工作要么。我读到了重写赋值运算符和副本 构造函数,但我不认为他们最终做了与正常情况不同的事情 赋值运算符和noraml拷贝构造函数。我用虚拟试了一下 赋值运算符也没有成功。以下是我的一个例子 与...合作。 “vec.emplace_back(& derivedEvent);”主要方法中的陈述 导致基类被添加到向量中。紧接着, 对象超出范围,向量不再包含derivedEvent的数据。我 编程仍然很新,所以我尝试的任何东西都可能做错了。
#include <string>
#include <vector>
////////////////////////////////////////////////////////////////////////////////
class CBaseEvent {
protected:
CBaseEvent(){}
std::string m_strBeginning;
std::string m_strEnd;
public:
CBaseEvent(std::string strBeginning, std::string strEnd)
: m_strBeginning(strBeginning), m_strEnd(strEnd){}
};
////////////////////////////////////////////////////////////////////////////////
class CDerivedEvent : public CBaseEvent {
private:
CDerivedEvent(){}
std::string m_strMiddle;
public:
CDerivedEvent(
std::string strBeginning,
std::string strMiddle,
std::string strEnd)
: CBaseEvent(strBeginning, strEnd),
m_strMiddle(strMiddle){}
};
////////////////////////////////////////////////////////////////////////////////
int main() {
std::vector<std::shared_ptr<CBaseEvent>> vec;
if (true) {
CDerivedEvent derivedEvent = CDerivedEvent("1", "2", "3");
vec.emplace_back(&derivedEvent);
}
return 0; //CRASH: possible corruption of the heap
}
答案 0 :(得分:1)
您正在堆栈中和if语句的范围内创建对象,一旦它超出该范围,对象将不再存在,并且当share_ptr被超出范围的向量销毁时您的程序将崩溃的主要功能,因为它将尝试销毁不再存在的对象。
这样:
if (true) {
CDerivedEvent derivedEvent = CDerivedEvent("1", "2", "3");
vec.emplace_back(&derivedEvent);
}
应该是:
if (true) {
CDerivedEvent* derivedEvent = new CDerivedEvent("1", "2", "3");
vec.emplace_back(derivedEvent);
}
它应该按照您的预期工作,但正如Jhon Purdy在下面的评论中所说,这将更合适:
int main()
{
std::vector<std::unique_ptr<CBaseEvent> > vec;
vec.push_back(std::unique_ptr<CBaseEvent>(new CDerivedEvent("1", "2", "3")));
return 0;
}
答案 1 :(得分:1)
我喜欢
std::vector<std::unique_ptr<CBaseEvent> > vec;
AngelCastillo使用的方法很多,但是它只有一个问题。
std::unique_ptr<CBaseEvent>(new CDerivedEvent(blah))
将导致通过CDerivedEvent
类型的指针删除类型为CBaseEvent*
的对象。由于CBaseEvent
没有虚拟析构函数(它甚至不是多态的),因此这是未定义的行为。
这可以通过
解决使用std::shared_ptr
,它在删除器内部保留类型信息。
std::vector<std::shared_ptr<CBaseEvent> > vec;
vec.push_back(std::make_shared<CDerivedEvent>(whatever));