Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 730
tru7 Avatar asked Apr 07 '16 10:04

tru7


People also ask

Does derived class does not inherit from the base class?

Explanation: The derived class inherits everything from the base class except the given things.

How do you prevent object slices?

Object slicing can be prevented by making the base class function pure virtual thereby disallowing object creation. It is not possible to create the object of a class that contains a pure virtual method.

Can you cast a base class to a derived class?

Likewise, a reference to base class can be converted to a reference to derived class using static_cast . If the source type is polymorphic, dynamic_cast can be used to perform a base to derived conversion.

Can a derived class be a friend of base?

Inheritance and Friendship in C++ If a base class has a friend function, then the function doesn't become a friend of the derived class(es). For example, the following program prints an error because the show() which is a friend of base class A tries to access private data of derived class B.


1 Answers

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;
}
like image 99
Meena Alfons Avatar answered Sep 28 '22 13:09

Meena Alfons