我想创建子类对象,它会与其他子类对象做出不同的 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/