我正在网上找到的库jsonplus用于更大的项目。
我需要将CJsonArray类的对象保存在 vector 中。
CJsonArray没有Copy-Constructor,但是具有指针属性,所以我尝试自己做一个(我第一次制作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()函数,该函数是一个抽象类,并且派生自该类。以下是相关的代码段:
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();
错误:
调试信息:
在第一个push_back上,第一个条目的成员已损坏。
在实现Copy-Constructor之前,该程序已经在第二次或第三次回推时崩溃了,我猜是因为vectore必须重新分配其条目并且找不到它们?令我难过的是,我第一次不得不处理这个问题。
所以我的问题是:复制构造函数做错了吗?还是我完全走错了路而与之无关?
我研究了许多其他类似问题的Stackoverflow问题,并尝试遵循那里的建议,但我想我在此过程中做错了什么。
如果需要提供其他信息,请告诉我。
在此先感谢您的帮助!
最佳答案
CJsonValue::Clone()
方法需要是虚拟的。如果CJsonArray
对象存储了CJsonValue
对象的集合(而不是CJsonValueNumber
或其他形式),则编译器无法知道CJsonValueNumber
是否要覆盖Clone()
方法(如果它不是虚拟的)。
这将导致始终调用CJsonValue::Clone()
而不是CJsonValueNumber::Clone()
。那时,您的数组中有NULL引用,这很可能导致0x00000000
(NULL
定义为0
或0x00000000
)的访问冲突。
由于CJsonValue
无论如何都是抽象类(CJsonValue::ToString()
方法是虚拟void),因此我也将CJsonValue::Clone()
设置为虚拟void。这将确保必须通过继承类来实现Clone方法。
总结一下,将CJsonValue::Clone()
的声明更改为:
LIB_PRE virtual CJsonValue * Clone() = 0;