指针的集合.复制构造函数问题
STL Set of pointers. Copy constructor issue
我正在使用最新版本的NetBeans在Ubuntu 11.10下使用c++开发一个项目。我将只发布与问题相关的最小部分代码。假设我有下面的代码来处理一个图形问题:
typedef map<Node*, double, DereferenceCompare> Transitions;
class Node {
int _nodeNumber;
Transitions _transitions;
}
每个Node对象都包含一个指向其他Node对象的指针映射。现在我们有:
typedef set<Node*, DereferenceCompare> Nodes;
class Network {
Nodes _network;
}
问题:我对为类Network编写复制构造函数感到困惑。我想要达到的目标是能够做到以下几点:
Network n1;
Network n2(n1);
//Have both n1 and n2 identical in structure but distinct in memory (deep copy).
我在以下假设中是否正确:如果我为Node类编写复制构造函数,它还需要复制Transitions容器。此时Transitions容器将保存指向旧节点的指针,因为新节点还不存在。
这是我在这里的第一篇文章。我希望我提供了明确和充分的信息。如果我没有把我的问题讲清楚,我可以进一步澄清。
我以前做过同样的事情。这很棘手:
Network::Network(const Network& b) {
//old to new mapping
std::unordered_map<Node*, Node*> mapper(b._network.size());
// duplicate all nodes without links
for(auto iter = b.begin(); iter != b.end(); ++iter) {
Node* new_node = new Node();
try {
_network.insert(new_node);
} catch (std::bad_alloc& e) {
delete new_node;
throw;
}
mapper[iter->first] = _network; //and map the old Nodes to new ones
new_node->_nodeNumber = iter->_node_number;
}
// THEN map the links
for(auto iter = b.begin(); iter != b.end(); ++iter) {
Node* new_node = mapper[iter->first];
//for each link in the old one
for(auto iter2 = iter->_transitions.begin();
iter2 != iter->_transitions.end();
++iter2)
{
//link to the corresponding new node
Node* connection = mapper[iter2->first];
new_node->_transitions[connection ] = iter2->second;
}
}
}
[EDIT]现在异常安全
还要注意,除了编译之外,我没有尝试以任何方式验证代码。我只记得几年前我遇到同样的问题时我是这么做的
考虑到你正在使用原始指针的关键元素,你不能使用默认的复制构造函数,但它是相当简单的做自己,如果你的Node
结构是一个树结构(即。不用担心循环)
Network(const Network& other)
{
if (this != &other)
{
for (auto it = other._network.begin(); it != other._network.end(); ++it)
{
_network.insert(new Node(*it));
}
}
}
Node(const Node& other)
{
if (this != &other)
{
_nodeNumber = other._nodeNumber;
for (auto it = other._transitions.begin(); it != other._transitions.end(); ++it)
{
_transitions[new Node(*it->first)] = it->second;
}
}
}
一个更简单的解决方案是自己存储Node
元素,这样容器就可以自动管理内存,或者使用一个智能指针来表示你想要的语义。
如果你允许在Node
结构中循环,那真的超出了复制构造函数的范围。您可能想要编写一个单独的"copy"函数,它从某个点开始扫描整个结构,并在整个过程中复制它。
在您的示例中,n1和n2将指向节点的相同实例。如果其中一个超出了作用域并删除了节点,那么另一个将指向释放的内存。
如果在Node和Transitions中使用原始指针,除了为Network和Node类提供复制构造函数外,还必须提供赋值操作符和析构函数。
使用智能指针代替。在您的情况下,如果"复制指向对象的指针"是一个复制语义,使用shared_ptr将使您不必手动编写复制构造函数等—默认实现将完成这项工作。如果复制语义是"复制对象本身":
-
如果性能不是问题-在容器中存储对象,使用默认copy c- for etc
-
如果性能很重要-为这两个类编写自己的copy c-tor等(或考虑使用第三方或编写自己的copy_ptr/clone_ptr)
- 变分模板递归构造函数问题
- C++重载构造函数问题
- 迷宫构造函数问题 [线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)]
- 构造函数问题<无法读取内存>
- 构造函数问题
- 另一个类中的类的构造函数问题
- 类构造函数问题
- 遇到构造函数问题
- C++ STM32用户定义的类构造函数问题
- 模板嵌套类的构造函数问题(复制 ctor 似乎覆盖了其他 ctor)
- 布尔构造函数问题的动态数组
- C++ 构造函数问题 // 继承的类
- C++:构造函数问题
- 类没有复制构造函数问题
- C++重载构造函数问题
- C++构造函数问题
- 在我的程序中"无符号"之前的预期主表达式(析构函数和构造函数问题)
- 复制构造函数问题C++:"0xC0000005: Access violation writing location 0x00000000."
- c++成员函数和构造函数问题
- c++派生类构造函数问题