我是一名新的计算科学专业的学生,在c ++方面经验不足。我一直在谷歌搜索几个小时,并没有遇到一个解决方案(说实话,我甚至找不到一个好的搜索声明)。基本上我在这里要学习的是如何为以下情况实现复制操作符:
#include <string>
#include <vector>
class foo
{
foo* parentObject;
std::vector<foo*> childObjects;
char a;
int *b;
public:
foo(char a, int* b) : a(a), b(b) {};
foo();
foo& operator =(const foo& other)
{
a = other.a;
b = new int(*other.b);
//parentobject???
//pretty sure i can figure childObjects if i can manageparentObject,
//but just in case there are some special stuff wanted to include.
return *this;
}
friend void getElements(std::string fpath);
};
为了更深入,我想从格式化的文本文件中读取类似树状层次结构(类似于XML)的相同类型的对象,并且只在内存中读取对象的一个实例(让假设这是getElements所做的事情,其余的是指向这些对象的指针(我们可以将其视为快捷方式的工作方式)。那是因为,我认为这将是最有效的方法,因为可能有很多对象,请纠正我,如果我错了。
但我也想跟踪结构,所以我决定采用这种父/子设计(再次可能是一个糟糕的选择,随时启发我)。由于我使用的读取方法(从父级到子级),即使我能找到初始化parentObject的方法,我也不能简单地初始化childObjects。因此我不能使用'new constructor()'赋值(或者我可以,但我只是不知道我可以)。
如果我需要(浅)复制操作符背后的原因不清楚,因为我没有初始化parentObject或childObjects,我需要稍后在阅读文本文档时分配它们(它真的感觉我不应该需要一个,但我想我会这样做。)。
我的实际代码真的难以阅读;因为这是一个只是为了在c ++上变得更好的项目,我没有重视编码风格)而且它更长,所以我创建了一个更简单的版本。我非常感谢任何评论,所以请随意写一篇。
编辑:我甚至无法正确复制粘贴(b的初始化)。 编辑:清除。
答案 0 :(得分:2)
如果有一个具有成员变量的对象来定义对象树,则复制构造函数或复制赋值运算符将不足以处理所有情况。你可能想:
a
和b
)。N
层父母和子女。N1
层父母和N2
层儿童。(1)可以由复制构造函数或复制赋值运算符处理。对于其他人来说,最好让extern
函数遍历树并复制树的右边部分。
答案 1 :(得分:0)
您遇到了XML节点自身复制的逻辑问题。实际上没有明确和直观的方法来复制作为树的一部分的XML节点。 C ++中的经验法则是:如果operator
没有直观的行为,请将其命名为命名函数。在您的情况下,我会创建一个foo& assign_from_content(foo&)
函数,它的作用类似于复制赋值,而static foo construct_from_content(foo&)
就像一个复制构造函数,只复制内容。
现在如何处理复制构造函数和复制赋值运算符? delete
他们。而是使用移动构造和移动分配。
foo& operator =(const foo& other)=delete;
foo& operator =(foo&& other) noexcept=delete;
{
disconnect_from_tree();
a = other.a;
delete b;
b = other.b;
other.b = null;
take_place_in_tree(other);
return *this;
}
//These are untested, they probably don't compile and have logical errors
void disconnect_from_tree() noexcept {
if (parentObject) {
auto it = std::find(parentObject->childObjects.begin(),
parentObject->childObjects.end(),
this);
if(it != parentObject->childObjects.end())
parentObject->childObjects.erase(it);
}
for(foo* child : childObjects)
child->parentObject = nullptr;
childObjects.clear();
}
//These are untested, they probably don't compile and have logical errors
void take_place_in_tree(foo& other) noexcept {
childObjects = std::move(other.childObjects);
parentObject = other.parentObject;
other.disconnect_from_tree();
for(foo* child : childObjects)
child->parentObject = this;
if (parentObject) {
auto it = std::find(parentObject->childObjects.begin(),
parentObject->childObjects.end(),
this);
if(it != parentObject->childObjects.end())
parentObject->childObjects.erase(it);
parentObject->childObjects.push_back(this);
}
}