编辑:我做了一些更改,并根据此帖子更新了代码 Kyle和Dieter的评论,所以我修复了我的Clone()函数和 添加了一个赋值运算符来实现三个规则。虽然这个 肯定非常需要修复,同样的错误占优势。也许是我的 赋值运算符错了?
我正在使用我在网上找到的更大项目的jsonplus库。 我需要在向量中保存Class 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()函数,它是一个抽象类和从它派生的类。以下是相关的代码段:
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:Access 违规读取位置0x00000000。
debuginfo软: 已经在第一个push_back上第一个条目的成员已经腐败。 在我实现Copy-Constructor之前,程序已经在第二次或第三次回击时崩溃了,我想因为vectore必须重新定位他的条目并且找不到它们?我很伤心,第一次不得不处理这个问题。
所以我的问题是:我复制构造函数是否错误?或者我完全是错误的方式,它与它无关?
我查看了许多处理类似问题的Stackoverflow问题,并试图遵循那里的建议,但我想我在此过程中做错了。
如果我需要提供更多信息,请与我们联系。
提前感谢您的帮助!
答案 0 :(得分:2)
CJsonValue::Clone()
方法需要是虚拟的。如果CJsonArray
对象存储CJsonValue
个对象的集合(而不是CJsonValueNumber
或其他对象),则编译器无法知道CJsonValueNumber
想要覆盖{{1}如果它不是虚拟的话。
这会导致始终调用Clone()
而不是CJsonValue::Clone()
。此时,您的数组中有NULL引用,这可能会导致您在CJsonValueNumber::Clone()
(0x00000000
定义为NULL
或0
)时发生访问冲突。
由于0x00000000
无论如何都是一个抽象类(CJsonValue
方法是虚空),我也会使CJsonValue::ToString()
虚拟空。这将保证必须通过继承类来实现Clone方法。
总结一下,将CJsonValue::Clone()
的声明更改为:
CJsonValue::Clone()