c++ - 多态、访问者、如何调用重载函数?

标签 c++ visitor-pattern

我想创建子类对象,它会与其他子类对象做出不同的 react (类可以欢迎另一个类,但不是全部) 代码原理源自访客设计模式:

class A
{
public :
    virtual bool isWelcoming(const A* other) const =0;
    virtual bool isWelcomable(const A* other) const =0;

};

class C;

class B: public A
{
public:

    virtual bool isWelcoming(const A* other) const 
    {
        return other->isWelcomable(this);
    }

    bool isWelcomable(const A* other) const 
    {
        return false;
    }

    bool isWelcomable(const B* other) const 
    {
        return true;
    }

    bool isWelcomable(const C* other) const 
    {
        return false;
    }

};

class C: public A
{
public:

    virtual bool isWelcoming(const A* other) const 
    {
        return other->isWelcomable(this);
    }

    bool isWelcomable(const A* other) const 
    {
        return false;
    }

    bool isWelcomable(const B* other) const 
    {
        return true;
    }

    bool isWelcomable(const C* other) const 
    {
        return true;
    }
};

但是当我这样做的时候

A *b1=new B;
A *b2=new B;
A *c=new C;

std::cout<<b1->isWelcoming(b2); //--> return false but I want true;
std::cout<<c->isWelcoming(b1); //--> return false OK;
std::cout<<b1->isWelcoming(c); //--> return false but I want true;

总是调用函数 isWelcomable(const A* other) 而不是重载函数 isWelcomable(const B* other) 或 isWelcomable(const C* other)。

这是正常的,因为 A::isWelcomable(const B* other) 和 A::isWelcomable(const C* other) 不存在...我不希望它们存在。

有没有办法调用 isWelcomable(const B* other) 或 isWelcomable(const C* other) 函数?

有了 dynamic_cast 但不是很干净?像这样:

class C;    
class B: public A
    {
public:

    virtual bool isWelcoming(const A* other) const 
    {
        return other->isWelcomable(this);
    }

    bool isWelcomable(const A* other) const 
    {
        const B* b=dynamic_cast<B*>(A);
        if (b)
            return isWelcomable(b);

        const C* c=dynamic_cast<C*>(A);
        if (c)
            return isWelcomable(c);

        return false;
    }

    bool isWelcomable(const B* other) const 
    {
        return true;
    }

    bool isWelcomable(const C* other) const 
    {
        return false;
    }

};

class C: public A
{
public:

    virtual bool isWelcoming(const A* other) const 
    {
        return other->isWelcomable(this);
    }

    bool isWelcomable(const A* other) const 
    {
        const B* b=dynamic_cast<B*>(A);
        if (b)
            return isWelcomable(b);

        const C* c=dynamic_cast<C*>(A);
        if (c)
            return isWelcomable(c);

        return false;
    }

    bool isWelcomable(const B* other) const 
    {
        return true;
    }

    bool isWelcomable(const C* other) const 
    {
        return true;
    }
};

感谢您的帮助。

更新: 使用 dynamic_cast 的解决方案,看起来有点像非循环访问者(感谢 TavianBarnes)可以做我想做的,但使用不推荐的 dynamic_cast。此外,该解决方案违反了 Liskov 替换原则。

我曾想过像 Kai Guther 建议的那样使用 getType(),用字符串代替枚举,但这个解决方案也违反了里氏替换原则,而且在我看来,这不仅仅是“dynamic_cast”解决方案。

所以,我认为没有不违反这个原则的解决方案,我会选择第一个解决方案,因为我觉得它更优雅,功能不必很快(只有一个操作响应用户操作)并且该应用程序不适用于嵌入式系统。

最佳答案

问题是您混淆了重载覆盖

B 类中,您有 isWelcomable 函数的三个重载,但只有一个重载A::isWelcomable 函数:

bool isWelcomable(const A* other) const;

这就是将由 other->isWelcomable(this) 调用的函数。

我建议你在使用多态性时养成使用override 特殊关键字的习惯,以确保你定义的函数确实覆盖了父类函数:

bool isWelcomable(const A* other) const override;  // Correct

bool isWelcomable(const B* other) const override;  // Incorrect, compiler error

如前所述,B::isWelcoming 函数不会返回任何内容,即使它被声明为返回任何内容。那当然会导致 undefined behavior这确实让所有关于行为的猜测都变得毫无意义。

关于c++ - 多态、访问者、如何调用重载函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51293061/

相关文章:

C++哈希算法

从 shared_ptr 和 boost::static_visitor 创建 boost::variant 的 C++ 模板元编程

c++ - 将访问者模式与模板派生类一起使用

rust - Visitor 特性如何只允许部分实现?

c++ - 无法创建二维数组

c++ - 非托管 C++ : How to dynamically load code?

java - 将表示数学表达式的树转换为没有多余括号的字符串

java - 使用不执行此操作的接口(interface)中指定的返回和参数类型相关的泛型实现方法

c++ - 在 C++ 中声明 INFINITY 的正确方法是什么?

C++ 编译时宏来检测 Windows 操作系统