我正在网上找到的库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定义为00x00000000)的访问冲突。

由于CJsonValue无论如何都是抽象类(CJsonValue::ToString()方法是虚拟void),因此我也将CJsonValue::Clone()设置为虚拟void。这将确保必须通过继承类来实现Clone方法。

总结一下,将CJsonValue::Clone()的声明更改为:

LIB_PRE virtual CJsonValue * Clone() = 0;

10-06 12:38