考虑以下抽象类:
class Abstract {
public:
// ...
virtual bool operator==(const Abstract& rhs) const = 0;
// ...
};
现在假设我正在从这个抽象类创建多个派生类。但是,每个算法在与自己的类型进行比较时使用不同的算法,在与任何其他派生类进行比较时使用通用算法。在以下两个选项之间,哪个更好,更有效?
选项A:
class Derived : public Abstract {
public:
// ...
bool operator==(const Abstract& rhs) const {
// Code for comparing to any of the other derived classes
}
bool operator==(const Derived& rhs) const {
// Code for comparing to myself
}
// ...
};
选项B:
class Derived : public Abstract {
public:
// ...
bool operator==(const Abstract& rhs) const {
const Derived* tmp = dynamic_cast<const Derived*>(&rhs);
if (tmp) {
// Code for comparing to myself
}
else {
// Code for comparing to any of the other derived class
}
}
};
我真的很好奇这些选项有哪些优点和缺点,因为C ++类型转换对我来说是一个相对神秘的话题。此外,哪种解决方案更“标准”,第二种解决方案是否会对性能产生影响?
可能有第三种解决方案吗?特别是如果有许多派生类,每个派生类都需要针对不同派生类的特殊比较算法吗?
答案 0 :(得分:2)
您的两种方法适用于不同的情况。对于选项A,静态类型rhs
用于决定调用哪个函数,而对于选项B,则使用动态类型。
因此,如果您希望程序根据参数的“真实”类型选择其行为,我认为您应该选择第二个选项。如果可以在编译时知道类型,则应使用选项A,因为它可以提供更好的性能。
答案 1 :(得分:1)
我认为如果你期望==运算符使用参数的动态类型,那么选项B就是你正在寻找的。例如:
class base
{
public:
virtual bool operator ==( const base& other ) = 0;
};
class derived : public base
{
public:
bool operator ==( const base& other ) { return false; }
bool operator ==( const derived& other ) { return true; }
};
int main()
{
base* a = new derived;
base* b = new derived;
std::cout << ( *a == *b ) << std::endl;
}
打印:
0
因此,即使实际动态类型为派生,也会调用operator ==(const base &amp; other)。
答案 2 :(得分:1)
你实际上可以使用其中一种技术来实现双重调度。这种方法在“更有效的C ++”的第31项中有详细描述。这是一个小例子:
#include <iostream>
class Derived1;
class Derived2;
class Base
{
public:
virtual bool operator==( Base& other) = 0;
virtual bool compare( Base& other) {return false;}
virtual bool compare( Derived1& other) {return false;}
virtual bool compare( Derived2& other) {return false;}
};
class Derived1 : public Base
{
public:
virtual bool operator==( Base& other) {return other.compare(*this);}
virtual bool compare( Base& other) {return false;}
virtual bool compare( Derived1& other) {return true;}
};
class Derived2 : public Base
{
public:
virtual bool operator==( Base& other) {return other.compare(*this);}
virtual bool compare( Base& other) {return false;}
virtual bool compare( Derived2& other) {return true;}
};
int main()
{
Base *a = new Derived1;
Base *b = new Derived1;
Base *c = new Derived2;
std::cout << (*a == *b) << std::endl;
std::cout << (*a == *c) << std::endl;
return 0;
}
输出:
1
0
答案 3 :(得分:0)
不幸的是,C ++没有多方法可以根据动态类型信息选择要调用的当前函数。您需要双重调度,访问者模式或其他一些技巧来实现该行为。