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?
Explanation: The derived class inherits everything from the base class except the given things.
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.
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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With