【发布时间】:2015-08-19 10:18:15
【问题描述】:
编辑:我做了一些更改并更新了这篇文章中的代码 Kyle 和 Dieter 的 cmets,所以我修复了 Clone() 函数并 添加了一个赋值运算符来满足三规则。虽然这 修复肯定是急需的,同样的错误盛行。也许我的 赋值运算符错了?
我正在使用我在网上找到的库 jsonplus 来完成一个更大的项目。 我需要将 CJsonArray 类的对象保存在向量中。 CJsonArray 没有 Copy-Constructor 但有一个指针属性,所以我尝试自己制作一个(第一次制作复制构造函数,我是 c++ 新手)。
这里是CJsonArray的相关部分:
cjsonarray.h
class CJsonArray : public CJsonValue
{
private:
std::vector <CJsonValue*> members;
public:
LIB_PRE CJsonArray();
LIB_PRE CJsonArray(const CJsonArray * value);
LIB_PRE CJsonArray(const CJsonArray &); //the added copy constructor
LIB_PRE CJsonArray& operator=(const CJsonArray&);
LIB_PRE ~CJsonArray();
cjsonarray.cpp
CJsonArray::CJsonArray(const CJsonArray& ori) : members(ori.members.size()) {
for (std::size_t i = 0; i < ori.members.size()-1; ++i)
members[i] =ori.members[i]->Clone();
}
CJsonArray& CJsonArray::operator=(const CJsonArray& ori){
for (std::size_t i = 0; i < ori.members.size() - 1; ++i){
this->members[i] = ori.members[i]->Clone();
}
return *this;
}
此外,我必须在 CJsonValue 中实现一个 clone() 函数,它是一个抽象类以及从它派生的类。以下是相关代码sn-ps:
cjsonvalue.h
enum CJsonValueType
{
JV_STRING,
JV_NUMBER,
JV_OBJECT,
JV_ARRAY,
JV_NULL,
JV_BOOL
};
class CJsonValue
{
private:
CJsonValueType type;
public:
LIB_PRE CJsonValue();
LIB_PRE virtual ~CJsonValue();
LIB_PRE CJsonValue(CJsonValueType type);
LIB_PRE virtual CJsonValue * Clone(); //the added Clone-Function
LIB_PRE virtual jstring ToString() const = 0;
LIB_PRE CJsonValueType GetType() const;
LIB_PRE virtual void Clear(){};
};
cjsonvalue.cpp
CJsonValue * CJsonValue::Clone(){
return NULL;
}
派生类示例,cjsonvaluenumber.h
class CJsonValueNumber : public CJsonValue
{
private:
int value;
public:
LIB_PRE CJsonValueNumber(int value);
LIB_PRE CJsonValueNumber(const CJsonValueNumber * value);
LIB_PRE CJsonValue * Clone();
LIB_PRE jstring ToString() const;
LIB_PRE void GetValue(int & number) const;
};
cjsonvaluenumber.cpp
CJsonValue * CJsonValueNumber::Clone(){
return new CJsonValueNumber(*this);
}
产生错误的main.cpp:
CJsonArray array1;
CJsonArray array2;
CJsonArray array3;
CJsonArray array4;
CJsonArray array5;
array1.AddMember("test1");
array2.AddMember("test1");
array3.AddMember("test1");
array4.AddMember("test1");
array5.AddMember("test1");
arrays.push_back(array1);
arrays.push_back(array2);
arrays.push_back(array3);
arrays.push_back(array4);
arrays.push_back(array5);
std::string str = arrays[0].ToString();
错误:
Message.exe 中 0x026574BD 处未处理的异常:0xC0000005:访问 违规读取位置0x00000000。
调试信息: 在第一个 push_back 上,第一个条目的成员已经损坏。 在我实现 Copy-Constructor 之前,程序在第二次或第三次推回时已经崩溃,我猜是因为 vectore 必须重新分配他的条目并且找不到它们?我很伤心,我第一次不得不处理这个问题。
所以我的问题是:我做错了复制构造函数吗?还是我完全走错了路,与它无关?
我查看了许多其他处理类似问题的 Stackoverflow 问题,并尝试遵循那里的建议,但我想我在此过程中做错了。
如果我需要提供更多信息,请告诉我。
提前感谢您的帮助!
【问题讨论】:
-
可能:三 (5) 规则 - 缺少赋值运算符
-
哇,感谢您的快速答复!我会仔细看看的。同时,你能告诉我是否在 cjsonvalue.cpp 中实现了 clone() 函数吗?我很不确定是否只在那里返回一个 NULL。
-
你知道
Clone不是虚拟的,对吧? -
我添加了一个赋值运算符(我希望我做得对)但问题仍然存在。我在 OP 中编辑了代码以反映我的更改。
-
出于好奇,
CJsonValueNumber(const CJsonValueNumber * value);应该服务于什么目的?return new CJsonValueNumber(*this);肯定不会调用它,并且您的JsonArray将在您添加的赋值运算符上调用未定义的行为,除非右值 完全 与this->members的大小匹配。既然你遇到了这么多麻烦,为什么不干脆把它结束并发布一个真实 MCVE 以便花更少的时间去想没有显示什么,以及更多时间了解是?
标签: c++ vector clone copy-constructor