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

Prevent derived class from casting to base

本文关键字:转换 基类 派生      更新时间:2023-10-16

我有

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可以做到这一点,但我不想重新实现它的所有方法。)

有办法做到这一点吗?

在Rect中声明SpecialRect的私有复制构造函数可以做到这一点,但有一个缺点:Rect取决于SpecialRect声明。【来自Jarod42的评论】

注意:请记住,您需要实现空构造函数,因为不会有默认构造函数。

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;
}

另一种解决方案是在Rect中声明显式默认复制构造函数。这样做的好处是不依赖于子类,但也有副作用。

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;
}