我有以下简单类
class base
{
public:
int x;
base &set(int y)
{
x = y;
return *this;
}
};
并希望创建一个具有附加功能的新功能,比如打印值x。所以我这样做:
class derived : public base
{
public:
void print()
{
cout << x << endl;
}
};
现在在主程序中我想做类似
的事情D.set(2).print();
然而编译器抱怨类类没有名为“print”的成员。
如果我尝试使用协变返回类型并将这两个类写为
class base
{
public:
int x;
virtual base &set(int y)
{
x = y;
return *this;
}
};
class derived : public base
{
public:
derived &set(int y)
{
x = y;
return *this;
}
void print()
{
cout << x << endl;
}
};
然后声明工作得很好,但是我被迫在两个类中为'set'重写完全相同的函数体,即使唯一改变的是返回类型。
如果稍后我需要更改base :: set的功能,那么我将不得不通过所有派生类来更改'set'函数...有什么方法可以避免这种情况吗?提前谢谢!
答案 0 :(得分:2)
根据您的具体情况,您可以使用CRTP:
template <class D>
class base {
D& set(int x) {
…;
return *static_cast<D*>(this);
}
};
class derived : base<derived> { … };
答案 1 :(得分:1)
C ++就像你说的那样工作,你在基类set
中说回归base&
,这就是C ++所做的。但是为了解决这个问题,你有很多方法。
首先,您不必强制使函数virtual
在派生类中覆盖它(请注意,虚拟调用比正常调用稍慢)。
其次,您可以将基类实现称为base::set
,因此代码如下:
class base {
...
base& set( int x ) {...}
};
class derived : public base {
derived& set( int x ) {
return static_cast<derived&>( base::set(x) );
}
};