【问题标题】:Changing behaviour of parent virtual function based on inherited type parameter基于继承的类型参数改变父虚函数的行为
【发布时间】:2016-12-10 21:47:47
【问题描述】:

我有一个包含一个基类和两个派生类的继承层次结构。

在基类中,我有一个虚函数:

virtual void interact(const Base &other) const;

在派生类中,它们都具有以下两个功能,这是必要的,因为这两个派生类之间的交互方式不同(即Derived1 和Derived1 的交互方式与Derived1 和Derived2 的交互方式不同):

void interact(const Derived1 &other) const;
void interact(const Derived2 &other) const;

我希望能够从vector<Base> 中获取两个对象并调用虚拟Base 类方法(例如base1.interact(base2))并在派生类中根据派生类型调用正确的函数。

有什么办法可以做到这一点,还是我的方法完全错误?

【问题讨论】:

  • 该技术被称为“双重调度”,有多种实现方式。
  • 同一个向量中的两个对象显然属于同一类型(向量的定义)。 “能够从一个向量中获取两个对象”很容易,但它们都是相同的类型。这似乎不是你的计划。我建议不要向下投射。

标签: c++ inheritance virtual-functions


【解决方案1】:

有什么办法可以做到这一点,还是我的方法完全错误?

您正在寻找的技术称为双重调度。
并非完全错误。例如,模式 visitor 是建立在相同概念之上的。

它遵循基于您问题中的详细信息的最小工作示例:

#include<iostream>

struct Derived1;
struct Derived2;

struct Base {
    virtual void interact(const Base &) const = 0;
    virtual void interact(const Derived1 &) const = 0;
    virtual void interact(const Derived2 &) const = 0;
};

struct Derived1: Base {
    void interact(const Base &other) const override {
        other.interact(*this);
    }

    void interact(const Derived1 &) const {
        std::cout << "Derived1/Derived1" << std::endl;
    }

    void interact(const Derived2 &) const {
        std::cout << "Derived2/Derived1" << std::endl;
    }
};

struct Derived2: Base {
    void interact(const Base &other) const override {
        other.interact(*this);
    }

    void interact(const Derived1 &) const {
        std::cout << "Derived1/Derived2" << std::endl;
    }

    void interact(const Derived2 &) const {
        std::cout << "Derived2/Derived2" << std::endl;
    }
};

void foo(const Base &lhs, const Base &rhs) {
    lhs.interact(rhs);
}

int main() {
    foo(Derived1{}, Derived1{});
    foo(Derived1{}, Derived2{});
    foo(Derived2{}, Derived1{});
    foo(Derived2{}, Derived2{});
}

它要求所有interact 方法都是虚拟的并且是基类的一部分。
基本思想是,将Base 的引用作为参数传递到的类会提升并将其自身用作(让我说)标签,以正确地将请求分派给正确的方法。
它通过回调调用者并将自身作为函数参数传递来做到这一点。

【讨论】:

    猜你喜欢
    • 2021-11-02
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 2013-03-28
    • 1970-01-01
    • 2013-10-24
    相关资源
    最近更新 更多