tru7
tru7

Reputation: 7212

Prevent derived class from casting to base

I have

class Rect{
   // stuff
};

and

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

SpecialRect inherits all the properties and methods from Rect except that I want to avoid non-explicit conversions of SpecialRect to the base class Rect.

In the code

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

Compiles with no errors. (I know that declaring the base class Rect as private would do it but I don't want to reimplement all its methods.)

Is there a way to achieve this?

Upvotes: 7

Views: 2820

Answers (1)

Meena Alfons
Meena Alfons

Reputation: 1230

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

Upvotes: 7

Related Questions