我想定义一个抽象基类X并强制执行以下操作:
a)从X继承的每个具体类Y定义了一个构造函数Y(int x)
b)应该可以测试两个Y对象是否相等。
对于a,一个不太好的解决方案是在X中放置一个纯虚拟的fromInt方法 哪个具体类必须定义。但我不能强制执行。
对于b),我似乎无法在X
中使用纯虚方法 bool operator == (const X& other) const =0;
因为在重写的类中,这仍然是未定义的。仅定义
是不够的 bool operator == (const Y& other) const { //stuff}
因为类型不匹配。我该如何解决这些问题?
答案 0 :(得分:3)
您可以通过将无参数构造函数设为私有并在基类中具有公共单个int参数构造函数来强制构造。只要基类有一些纯虚方法,那么你的子类必须调用该构造函数。
至于运算符==,尝试定义
bool operator == (const BaseClass& other) const { .. };
在所有子类中。最糟糕的情况是,您可以在基础中定义一个纯粹虚拟的公共等于(const BaseClass& other)方法。
编辑:强制构造函数并不完全正确。我建议强制子类调用单个参数构造函数。它们可以有一个无参数构造函数,它将常量传递给构造函数中的基数。
答案 1 :(得分:2)
对于b),您可以在X中定义virtual bool operator == (const X & other) const = 0
。
你不能在比较中使用const Y & other
作为参数,但是Ys会自动转换为Xs然后你可以使用dynamic_cast查看它是否是一个你可以比较的类。
答案 2 :(得分:2)
有一个简单的解决方案。
// Class X
// (... some documentation ...)
//
// ** NOTE: All subclasses of X must have a constructor that takes a single int,
// ** and overload operator==.
class X {
...
答案 3 :(得分:0)
a - 如果您使用CRTP以及所有用户代码必须继承的中介,朋友,模板化子类,则应该可以使用。像这样:
struct X
{
virtual bool compare(X const&) const = 0;
private:
X();
template < typename T >
friend struct client_base; // don't recall the correct code here.
};
template < typename Sub >
struct client_base : X
{
// use boost::concepts to verify Sub has Sub(int)
Sub() : X() {}
};
struct Y : client_base<Y>
{
Y(int);
bool compare(X const& x)
{
if ((Y* other = dynamic_cast<Y*>(x)) && *other == *this) return true;
return false;
}
};
显然,我已经离开了很多让你想出这个完整的解决方案。
答案 4 :(得分:0)
a)对我来说没有意义,但你可以创造一些东西
template< typename T >
Base* create( int x )
{
return T::create( x );
}
for b)向谷歌询问c ++中的“多方法”实现
答案 5 :(得分:0)
强制从整数构造是没有任何意义的:每个派生类都可以自由地定义它的构造函数。但是,你可以强制它们将一个整数传递给基类......不管它是否更有意义。
operator==
也是扭曲的,但你可以得到它的本质:
class Base
{
public:
bool operator==(const Base& rhs) const;
bool operator!=(const Base& rhs) const { return !(*this == rhs); }
private:
virtual bool equals(const Base& rhs) const = 0; // will pass only objects
// of the same dynamic type
};
bool Base::operator==(const Base& rhs) const
{
return typeid(*this) == typeid(rhs) && this->equals(rhs);
}
bool Derived::equals(const Base& rhs) const // We KNOW Base is actually a Derived
{
return *this == static_cast<const Derived&>(rhs);
}
您可以尝试使用模板和CRTP对其进行一些美化,但如果继承了Derived
该怎么办?它不会成立。