我正在编写代码,要求我保留两种类型的对象(例如类Derived1和类Derived2)的集合,这些对象具有相同的基类(例如,类Base)。基类还有一个纯虚函数,在这两个派生类中都有一个实现。
我使用指向基类对象的点向量来跟踪所有这些对象(即向量< * Base> myCollection)。但是,我经常需要复制这个载体。
我尝试在基类中创建一个复制函数,以便我可以创建Derived1或Derived2的其他实例。但是,我注意到了一些奇怪的行为。
以下是此行为的示例:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class A
{
public:
int member;
string name;
A(int x, string str = "Base"): member(x), name(str) {}
A* CreateCopy()
{
A tmp = A(member); // tmp: member = 77, name = "Base"
return &tmp; // &tmp: member = 77, name = ""
}
};
class B : public A
{
public:
B(int x) : A(x, "Derived Class") {}
};
int main()
{
A* ptr = &B(77); // &tmp: member = 77, name = ""
B test(77); // test: member = 77, name = "Derived Class"
A* ptr2 = &test; // *ptr2: member = 77, name = "Derived Class"
A* newPtr = ptr->CreateCopy(); // *newPtr: member = 77, name = ""
return 0;
}
当我创建对象B并在同一行上分配对象的引用时,我将失去名称成员的正确性。但是,当我创建对象,然后分配它的引用时,它的工作原理。不幸的是,我的CreateCopy()方法遇到了同样的问题。
这里发生了什么以及复制指针向量的最佳方法是什么?是否可以在不使用“new”运算符的情况下执行复制?使用此运算符时,似乎更容易发生内存泄漏。
非常感谢你的建议!
答案 0 :(得分:2)
对于A* ptr = &B(77);
,B(77)
是一个临时对象,当表达式结束时将被销毁,然后ptr
将成为悬空指针。
有关
A* CreateCopy()
{
A tmp = A(member); // tmp: member = 77, name = "Base"
return &tmp; // &tmp: member = 77, name = ""
}
tmp
是一个局部变量,当它超出函数范围时将被销毁,这意味着CreateCopy()
将返回一个悬空指针。
是否可以在不使用&#34; new&#34;的情况下执行复制。运营商?使用此运算符时,似乎更容易发生内存泄漏。
您可以使用智能指针来避免手动内存管理。例如std::unique_ptr或std::shared_ptr。