gpt4 book ai didi

C++ 复制指针指向的数据

转载 作者:太空宇宙 更新时间:2023-11-04 14:13:50 33 4
gpt4 key购买 nike

我是一个长期的读者,也是第一次张贴……我已经搜索了很长时间,很难找到现在真正让我困惑的事情的答案。我一定遗漏了一些东西,因为我相信这应该有效......

我正在尝试创建一个数据表类,该类将包含传递给它的对象的拷贝。我决定使用 std::map 来包含这些数据。请参阅下面的示例代码:

typedef std::map <std::string, myVar *> myVarContainer;

class myObj
{
public:
myObj(void);
virtual ~myObj(void);

void setVar(std::string Key, myVar & Var);

myVar * getVar(std::string Key);

void release()
{
for (myVarContainer::iterator i = VarContainer->begin(); i != VarContainer->end(); ++i)
{
delete (i->second);
}

VarContainer->clear();
};

myVarContainer * VarContainer;

};

typedef std::map <myVar, myObj *> myRow;

class myTable
{
public:
myTable(void);
virtual ~myTable(void);

void addDataPoint(myVar RowID, myVar ColID, myObj * Data)
{
std::map <myVar, myRow *>::iterator i = m_Rows->find(RowID);

if (i == m_Rows->end())
{
m_Rows->insert(make_pair(RowID, new myRow()));
}
i = m_Rows->find(RowID);

// i thought the below line would be creating a copy of the data?
// I thought this logic went:
// 1. create a new object copied from the value of 'Data'
// 2. return a pointer to this object and pair with the 'colID'
// 3. make this into a pair and insert into the main map
i->second->insert(make_pair(ColID, new myObj(*Data)));
};

protected:

std::map <myVar, myRow *> * m_Rows;
}


int main()
{

myVar a, b, c, d;

myObj * o = new myObj();

o->setVar("test", a);
o->setVar("test2", b);

myTable * tab = new myTable();

myVar x1, y1, x2;

tab->addDataPoint(y1, x1, o);

o->release(); // this clears out both 'o' and the values in 'tab'!?!?

//at this point tab has no data in its object at y1,x1???

o->setVar("test3", c);
o->setVar("test4", d);

tab->addDataPoint(y1, x2, o);
}

我注意到我的数据被过早删除了。我相信我错过了一些东西......我以为我正在创建指针引用的数据的拷贝,然后在我的 map 中存储一个新实例的指针......有什么想法吗?感谢您的帮助!

最佳答案

因此在容器中使用(拥有)原始指针的问题之一是您需要自己手动删除实例。我假设 myObj::~myObj 就是这样做的(在删除容器本身之前迭代容器删除所有元素)。

行:

i->second->insert(make_pair(ColID, new myObj(*Data)));

是从数据复制构造一个 myObj。

不幸的是,因为您没有为 myObj 定义复制构造函数,编译器将为您生成一个复制构造函数,它只会将指针复制到 VarContainer 成员。它不会创建 map 的新拷贝或它在内部引用的任何内容。创建拷贝后,您将拥有两个实例,它们都指向同一个容器,并且两个实例都认为它们拥有它。当第一个被破坏时,它似乎没问题,但实际上让另一个实例指向释放的内存。一旦生命周期最长的实例尝试使用此容器指针做任何事情,就会发生一些不好的事情。

您可以通过按值而非指针存储映射来解决此问题:

typedef std::map<std::string, myVar> myVarContainer;
typedef std::map<myVar, myObj> myRow;

同时将 myObj::VarContainer 更改为非分配成员。这意味着现在可以正确复制所有内容,并且拷贝不会引用原始文件中的任何内容。

请注意,您也可以使用智能指针(例如 std::shared_ptr)代替原始指针,但您仍然需要小心,因为虽然复制是安全的,但它们共享原始数据可能不是您所期望的。

您应该看看以下内容:

http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming )

关于C++ 复制指针指向的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12787972/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com