C++ 两个派生类中包含彼此的对象(包括问题)

Posted

技术标签:

【中文标题】C++ 两个派生类中包含彼此的对象(包括问题)【英文标题】:C++ two derived classes have objects of each other in them (include issue) 【发布时间】:2018-04-25 08:45:28 【问题描述】:

我有以下文件

json.hpp jsonobject.hpp jsonarray.hpp

在每个文件中都有一个类定义(JSON, JSONObject : public JSON, JSONArray : public JSON),后两个具有以另一个作为参数的函数(并且不是作为引用类型,所以简单的前向声明并不能解决问题)。 这些文件是:

json.hpp:

#ifndef _JSON
#define _JSON

#include <string>
#include <iostream>
#include "../../lib/simplejson/json.hpp"

class JSON
    protected:
        std::string content;
    public:
        JSON(std::string content) : content(content)
        

        operator std::string()
        return content;

        friend std::ostream& operator<<(std::ostream&, JSON&); 

;

inline std::ostream& operator<<(std::ostream& os, JSON& content)

    os<<content.content;
    return os;

#endif

jsonobject.hpp:

#ifndef _JSONOBJECT
#define _JSONOBJECT

#include "json.hpp"
class JSONArray;

class JSONObject : public JSON 
    public:
        JSONObject(std::string= "");

        JSONObject get(std::string);

        template<typename T> void put(std::string, T);

        operator int();

        JSONObject operator[](int);

;

inline JSONObject::operator int() return atoi(content.c_str());


inline JSONObject::JSONObject(std::string content) : JSON(content) 

inline JSONObject JSONObject::get(std::string key) 
    json::JSON obj = json::JSON::Load(content);
    JSONObject json(obj[key].dump());
    return json; 

template<typename T> inline void JSONObject::put(std::string key, T value) 
    json::JSON obj = json::JSON::Load(content);
    obj[key] = value;
    content = obj.dump();  template<> inline void JSONObject::put<JSON&>(std::string key, JSON& value) 
    json::JSON obj = json::JSON::Load(content);
    json::JSON obj2 = json::JSON::Load((std::string)value);
    std::cout<<obj2<<std::endl<<std::endl;
    obj[key] = obj2;
    content = obj.dump();      template<> inline void JSONObject::put<JSONObject>(std::string key, JSONObject value)   //here is JSONObject used in a manner which requires it not to only be forward-declared
    (*this).put(key, dynamic_cast<JSON&>(value));  template<> inline void JSONObject::put<JSONArray&>(std::string key, JSONArray& value) 
    (*this).put(key, dynamic_cast<JSON&>(value)); 
#endif

jsonarray.hpp:

#ifndef _JSONARRAY
#define _JSONARRAY

#include "jsonobject.hpp"

class JSONArray : public JSON
    public:
        JSONArray(std::string = "[]");

        JSON operator[](int n);

        template<typename T> void add(int, T);

;

inline JSONArray::JSONArray(std:: string content) : JSON(content)


inline JSON JSONArray::operator[](int n)

    json::JSON obj = json::JSON::Load(content);
    JSONObject json(obj[n].dump());    //Here is JSONObject instantiated, which does not work with only forward-declarataion
    return json;


template<typename T> inline void JSONArray::add(int n, T t)

        json::JSON obj = json::JSON::Load(content);
        obj[n] = t;
        content = obj.dump();

template<> inline void JSONArray::add<JSON>(int n, JSON t)

        json::JSON obj = json::JSON::Load(content);
        json::JSON obj2 = json::JSON::Load((std::string)t);
        obj[n] = obj2;
        content = obj.dump();

#endif

我错过了什么?我也试过把它们都放在一个文件中,也没有帮助。

【问题讨论】:

【参考方案1】:

不,这样对你没有帮助。您需要将实现移动到一个单独的类中以打破循环并在其中一个类中使用实现的前向引用。该技术被称为柴郡猫,它类似于:

A.hpp
// AImple uses B.
class AImpl;

class A

    AImpl* impl;
public:
    void f(); // f uses impl.
;

B.hpp

#include "a.hpp"

class B

    A a; // B can use A here.
;

A.cpp
#include "a.hpp"
#include "aimpl.hpp"

void A::f()

   impl -> f();


AImpl.cpp
#include "b.hpp"
#include "AImpl.hpp"

// implementation which uses B.

【讨论】:

以上是关于C++ 两个派生类中包含彼此的对象(包括问题)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 类型将基础对象转换为派生对象

C++一道题 跪求解答

C++:友元函数,派生类

指向派生对象的基类指针的 C++ 排序容器

抽象类

在 C++ 中将派生类对象分配和访问到基类“指向指针”对象