Reputation: 2399
Say i have an interace like
#include<iostream>
struct Interface
{
virtual void fun() = 0;
};
struct IType : Interface
{
void fun() override
{
std::cout<<"non const fun()";
}
};
class Type
{
private:
Interface &intr; // I can't declare intr as const i need to ascess non const fun()
public:
// I put it as a const for default value
Type(const Interface& obj = IType()) : intr{const_cast<Interface&>(obj)} // Is const_cast is safe or how to do it ?
// What is god idea to do it should i need to remove const and default value but i need a default constructor
{
intr.fun();
}
};
int main()
{
Type obj;
return 0;
}
Thanks.
Upvotes: 0
Views: 714
Reputation: 22176
Reference as class member is rarely a good idea. You need an object, passed from the outside, that will outlive your class object. You cannot use default argument and you cannot use a temporary for initialization. Typically, if you need to pass different types that inherit from an interface, this is solved with (smart) pointers.
Type(const Interface& obj = IType()) : intr{const_cast<Interface&>(obj)} //Is const_cast is safe or how to do it ?
It depends. You can cast away constness only if the real object is not const. So this:
IType itype{};
Type {itype};
would be valid, but this:
const IType itype{};
Type {itype};
would be invalid.
Your default argument is invalid anyway, because that default is a temporary object that dies immediately once constructor finishes, which means you cannot use intr
member outside of this constructor.
I'm not 100% sure if const_cast
is valid on temporary or not, but that doesn't matter in this case.
The solution is to use (smart) pointers:
class Type
{
private:
std::shared_ptr<Interface> intr;
public:
Type(std::shared_ptr<Interface> obj = std::make_shared<IType>()) : intr{std::move(obj)}
{
intr.fun();
}
};
The default choice for smart pointer is std::unique_ptr
, but use of reference suggests that you wanted access to object from the outside of the class as well, and std::shared_ptr
will allow that.
Upvotes: 3