我应该动态演员

时间:2011-11-27 14:50:43

标签: c++ polymorphism

我的问题是,我有一个派生类的基类。我在基类中有一个重载的+ =运算符,但我只希望能够添加相同类型的派生类。我这样做是通过返回lhs并在它们不是同一类型时产生警告消息。

class base{
   int variable;
   public:
   base(int v);
   base & operator+=(const base & rhs);

class a: public base{
}

class b: public base{
}

base & operator+=(const base & rhs){
if(type_same(const & rhs){
    variable+=rhs.variable; }
return *this
}

a first(1);
a second(5);
b third(2);

first+=second // first.variable now =6
second+=third // warning produced second.variable still = 5

之前我从未使用过动态强制转换,所以我的问题是使用它和typeid进行检查是否可行/可取,以确定传递的类型是否相同。我的替代方案是每个派生类的字符串常量名称。

3 个答案:

答案 0 :(得分:4)

为什么首先在基类中使用operator +?如果您只是将operator+的正确类型放入ab类,那么它就可以正常运行,而不会有dynamic_cast

dynamic_cast通常暗示您的类型设计不合理,应避免使用。在所描述的场景中,您可以毫不费力地使用dynamic_cast。如果不是,那么ab不应该来自base,因为它们的行为方式不同。从用户角度考虑:通过从a派生base,您告诉用户a可以用作base。如果方法需要实际类型,请将其向下移动而不是将其放入基本接口。

正确使用btw。将dynamic_cast rhs改为当前类型(即dynamic_cast<b*>(&rhs))并且如果返回非零值,那么rhs确实是正确的类型(但是,考虑一下如果有一个派生自b的类,则会发生!)

答案 1 :(得分:2)

要解决您在帖子中说明的问题,dynamic_cast和RTTI绝对是正确的工具。但是,在运行时发出警告,同时为'+'操作提供编译时支持可能会指向用户设计中的问题您的API不会完全期望您的API提供的行为。

答案 2 :(得分:1)

我的看法:您可以使用CRTP

以下代码将在编译时发出类型不匹配错误,如其他人所建议的那样。

template <typename Derived>
class base{
   int variable;
 public:
   base(int v) { variable = v; }
   Derived& operator+=(const Derived& rhs);
};

struct a: base<a> {
    a(int v): base<a>(v) {}
};

struct b: base<b> {
    b(int v): base<b>(v) {}
};

template <typename Derived> 
Derived& base<Derived>::operator+=(const Derived& rhs) 
{
    variable += rhs.variable; 
    return static_cast<Derived&>(*this);
}

int main(int argc, const char *argv[])
{
    a a1(1), a2(2);
    b b1(1), b2(2);

    a1 += a2;
    b1 += a2; // compile time error :)

    return 0;
}

即使您真的想要将运算符参数键入为base&,您至少也可以获得使用static_cast<>的好处,因为转换是精确的,并且在运行时定义良好。我可以在一些

中扩展这个想法