防止派生类从强制转换为基础

时间:2016-04-07 10:24:21

标签: c++ inheritance casting object-slicing

我有

class Rect{
   // stuff
};

class SpecialRect:public Rect{
private:
     operator const Rect(){return *this;}          // No implicits casts to Rect
public:
     // stuff
};

SpecialRect继承了Rect的所有属性和方法,除了我想避免将SpecialRect非显式转换为基类Rect。

在代码中

SpecialRect oneSpecial;
Rect aRect=oneSpecial;          // I want this to not compile. (to remind-me to declare aRect as SpecialTect)

编译没有错误。 (我知道将基类Rect声明为private是可以的,但我不想重新实现它的所有方法。)

有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:5)

Declaring private copy constructor of SpecialRect in Rect will do the trick but with one disadvantage: Rect depends on SpecialRect declaration. [from Jarod42's comment]

Note: Remember you need to implement the empty constructor because there will not be default constructor.

class SpecialRect;

class Rect {
public:
    Rect(){}

private:
    Rect(const SpecialRect&);
    //Rect(const SpecialRect&) = delete; // c++11
};

class SpecialRect : public Rect {

};


int main()
{
    SpecialRect sr;
    //Rect r1 = sr; // error: 'Rect::Rect(const SpecialRect&)' is private
    //Rect r2(sr); // error: 'Rect::Rect(const SpecialRect&)' is private

    Rect r3;
    Rect r4(r3);
    Rect r5 = r3;
    return 0;
}

Another solution is to declare explicit default copy constructor in Rect. This has the benefit of not depending on sub classes but has side effects.

class Rect {
public:
    Rect(){}
    explicit Rect(const Rect&);
};

class SpecialRect : public Rect {

};

int main()
{
    SpecialRect sr;
    //Rect r1 = sr; // Prevents this
    Rect r2(sr);    // Leaves this

    Rect r3;
    Rect r4(r3);
    //Rect r5 = r3;  // Side Effect: Prevents this

    return 0;
}