如何让类相互继承?

Posted

技术标签:

【中文标题】如何让类相互继承?【英文标题】:How to make classes inherit each other? 【发布时间】:2020-07-26 02:31:52 【问题描述】:

我有两个类ClassOneClassTwo,每个类都在一个单独的文件.h.cpp 中,如下所示:

// ClassOne.h file
#include <ClassTwo.h>
class ClassOne : public ClassTwo 
protected:
    type m_string; // Required for "ClassTwo"


// ClassTwo.h file
#include <ClassOne.h>
class ClassTwo : public ClassOne 
public:
    method1(); // <---|
    method2(); // <- Required to be available in class ClassOne.
    method3(); // <---|

正如您在前面的代码中看到的,这两个类相互继承,但该代码出现错误error C2504: 'ClassOne': base class undefinederror C2504: 'ClassTwo': base class undefined

这样做的目的是我希望“ClassTow”的成员函数在“ClassOne”中可用,但“ClassTwo”需要“ClassOne”中的成员变量。

如何让两个类相互继承?

【问题讨论】:

您要解决什么问题?你能用 CRTP 解决问题吗? class X : public class Y 表示 Y 是带有一些额外内容的 XX 不可能同时是带有一些额外内容的 Y 听起来你应该有 1 个班级,而不是 2 个 @LionKing 可能将指向 ClassOne 对象的指针(或引用)传递给 ClassTwo 对象的构造函数,并让 ClassTwo 持有指向 ClassOne 对象的指针/引用成员变量?然后每个类对象可以通过它持有的成员变量调用另一个对象上的方法。 通过一个实际的具体示例来决定如何正确构建代码会容易得多。 您想通过这个组织解决什么问题 【参考方案1】:

也许 CRTP 可以解决您的问题。首先,创建类ClassOne 作为使用类型ClassTwo 作为参数的模板。这个类型应该是继承自ClassOne的类:

template<typename ClassTwo>
class ClassOne

public:
    void methodOne() 
        if (you need to use methods of ClassTwo) 
             static_cast<ClassTwo*>(this)->methodTwo();
    
;

然后将ClassTwo定义为继承ClassOne的那个,用自己指定模板参数:

class ClassTwo : public ClassOne<ClassTwo>

public:
    void methodTwo() 
        if (you need to use methods of ClassOne) 
             methodOne();
    
;

更新:这是一个很难解决问题的方法。还有其他更简单的方法,例如使用虚拟方法:

class ClassOne

public:
    void methodOne() 
        if (you need to use methods of ClassTwo) 
             methodTwo();
    
    virtual void methodTwo() = 0;
;

class ClassTwo : public ClassOne

public:
    void methodTwo() override 
        if (you need to use methods of ClassOne) 
             methodOne();
    
;

这两种方法各有利弊。我们需要详细了解您的任务,以便建议哪个更好。

【讨论】:

虽然这可行,但我很难想象为什么有人想要循环继承?? @YunfeiChen 如果我们忘记问题本身并尽量避免ProblemXY偏差,那么作者的实际问题是“如何调用彼此的方法”。这可以通过多种方式解决,例如使用虚拟函数。 CRTP 可能更接近作者的意思。 第二种方法很好,但会使该类成为抽象类,对吧? @LionKing,类是抽象的,但对象必须实现所有抽象方法。这不是你需要说ClassOne使用ClassTwo的一些方法吗?你要实现它们,不然怎么用? 虽然这不是我想要的,但除了这个没有解决办法。无论如何,谢谢。【参考方案2】:

如何让类相互继承?

一个类不可能继承它的孩子。基只能在类定义中指定,除非已指定,否则类不能用作基。没有办法以这样的方式对这两个定义进行排序,使两者都在彼此之前。因此,这是不可能的。

这样的继承也是自相矛盾的,因为类对象在其自身中包含作为子对象的基类。因此,你会以一内二内一内二内一内二内一内二内一内二内一内二内的情况结束……你能看到这是怎么回事吗?它无处可去。该对象无限大,因为它包含无限深的继承层次结构。

用另一种方式来表达:继承层次结构可以看作是一个有向图。继承层次图不能包含循环。


这样做的目的是我希望“ClassTow”的成员函数在“ClassOne”中可用,但“ClassTwo”需要“ClassOne”中的成员变量。

您可以有两个类,它们都可以访问所有数据成员和函数,如下所示:

struct ClassOne 
    // all the member functions
    // all the data members
;

struct ClassTwo : ClassOne 
    // nothing here
;

现在您有两个类,它们都可以访问相同的数据成员和成员函数。

【讨论】:

“ClassTwo”需要在“ClassOne”中找到一个变量成员,再看我的代码。 @LionKing ClassTwo 在我的示例中具有该成员变量,因为它继承了它。 对不起,“ClassTwo”继承了“ClassOne”,则成员变量可用,但“ClassOne”不继承“ClassTwo”,所以“ClassTwo”中的所有成员函数都会在“ClassOne”中不可用。 @LionKing 根据我的建议,如果您将所有成员函数都放在 ClassOne 中,而没有放在 ClassTwo 中,那么 ClassTwo 就没有 ClassOne 中可能缺少的任何成员函数。

以上是关于如何让类相互继承?的主要内容,如果未能解决你的问题,请参考以下文章

Java面向对象—— 继承

面向对象 封装 继承

设计模式——代理模式与装饰模式的异同

继承与修饰符

父类对象与子类对象相互转化的条件是啥?如何实现它们的相互转化?

java 继承