srilakshmikanthanp
srilakshmikanthanp

Reputation: 2399

Pass Interface object to constructor c++?

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

Answers (1)

Yksisarvinen
Yksisarvinen

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

Related Questions