【问题标题】:C++ Parent Class that calls method in Child Class, that call Parent Class MethodC++父类调用子类中的方法,调用父类方法
【发布时间】:2016-02-14 23:34:39
【问题描述】:

如果我有此代码,例如:

class ChildOne
{
    ChildOneFunc()
    {
        Parent::ParentFunction();
    }
    CallNeighbour()
    {
        ChildTwoFunc();
    }
};

class ChildTwo
{
    ChildTwoFunc();
};

class Parent : public virtual ChildOne, public virtual ChildTwo
{
    Parent() //Constructor
    {
        ChildOneFunc();
    }
    ParentFunction();
};

怎么可能做到这一点? 因为在 Child 2 中,Class Parent 没有定义和前向声明 只给我错误。

第二个问题:

如何从 Childtwo 调用 CildOneFunction()?

【问题讨论】:

  • 通常,派生类称为“子类”,基类称为“父类”。你把它颠倒过来,这真的很混乱。
  • 哦,我以为我将子类继承给父类: class Parent : public virtual ChildOne,public virtual ChildTwo 不是这样吗?
  • 你永远不会继承 to (不是在现实生活中也不是在 C++ 中),但总是 from (inherit='erben' 在德语中,不是'vererben')
  • @PeterLustig,在您的代码示例中,ChildOneChildTwo 没有链接,而 Parent 是它们的派生类。比如说,ChildOne 是“机械”,ChildTwo 是“轮式”,Parent 可以是“汽车”

标签: c++ function oop inheritance parent-child


【解决方案1】:

您可以通过静态或动态多态来实现第一个。避免使用“父”和“子”的混淆命名法,这里有一种使用动态多态性的可能性:

struct base /* aka ChildOne */
{
  virtual void func() const = 0;
  void basefunc() { func(); }
};

struct derived /* aka Parent */
: base
{
  void func() const override;
};

这里,derived 类与base 具有is-a 关系:derived 类型的对象也是@987654325 类型的对象 @。动态多态性是通过虚拟表实现的,这会产生一些(小的)运行时开销。这可以通过 CRTP 使用静态多态性来避免:

template<typename Derived>
struct base 
{
  void basefunc() { static_cast<const Derived>(this)->func(); }
};

struct derived
: base<derived>
{
  void func() const;
};

不需要虚拟表查找,因为没有使用virtual 函数。

【讨论】:

    【解决方案2】:

    简短的回答是:一般情况下您不能这样做,但您可以使用dynamic_cast 添加检查。

    您使用Parent 名称定义派生类,使用Child 定义基类有点令人困惑,但我会使用您的术语。
    ChildTwo 类没有通过继承与 ChildOne 链接,因此在 ClassTwo 的任何方法中,您只有一个 ClassTwo 对象,它可能无法实现 ChildOne 方法。但您可以使用dynamic_cast 进行检查:

    ChildTwoFunc()
    {
        auto thisAsChildOne = dynamic_cast<ChildOne*>(this);
        if (thisAsChildOne != nullptr)
        {
            thisAsChildOne->ChildOneFunc();
        }
    }
    

    在这里,我们首先尝试通过所有必要的运行时检查将this 转换为指向ChildOne 的指针。如果this 不是从ChildOne 派生的任何类的对象(在您的示例中,如果this 不是Parent),则此dynamic_cast 将返回nullptr。如果转换成功,我们调用该函数。

    对于任意的ChildTwo,您可以强制编译器使用reinterpret_cast 调用此函数,但这是非常不安全

    有关dynamic_cast的更多信息,您可以阅读here

    【讨论】:

    • 不要这样做。频繁使用dynamic_cast 是糟糕的编程设计和风格的标志。
    • @Walter,在作者的代码中,我们有两个类ChildOneChildTwo,它们没有通过继承链接,但他想从另一个类调用一个类的方法。当然,这是一个糟糕设计的强烈迹象,但是你怎么能在没有dynamic_cast 的情况下调用这些方法呢?我的意思是,在这个类结构中?
    猜你喜欢
    • 2011-09-04
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    相关资源
    最近更新 更多