Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

should always return a pointer to class in interface design?

Tags:

c++

oop

I wish I could return an object of virtual base class so that I won't need to deal with the memory management(the idea of function programming also stimulate this pursuit). That means I am looking for some things like below:

class Car
{
  public:
     virtual int price() = 0 ;
     virtual string brand() = 0 ;
}

class Interface
{
  public:
     virtual Car giveMeACar() = 0 ;
     virtual vector<Car> listMeAllTheCars() = 0 ;
}

However, this won't even compile due to that Car is an abstract interface, with an error message :

invalid abstract return type for member function 'virtual Car giveMeACar() = 0 ; because the following virtual functions are pure within 'Car' : int price()
string brand() ;

So, does that means I have to revise the interface to something like below and manager the memory myself (delete the instance after using it) - ruling out the option of using smart pointer.

class Interface
{
  public:
     virtual Car* giveMeACar() = 0 ;
     virtual vector<Car*> listMeAllTheCars() = 0 ;
}

My question is : is this the only option I have when design an interface where every things(class) is abstract?

Returning an object of interface class is perfect valid in Java. C++ seems to be litter bit verbose and counter intuitive in this facet. More than often, I feel C++ is "pointer to object programming language" instead of a "object programming language" because without a pointer you can not get too much benefit of object programming.

like image 256
pierrotlefou Avatar asked Sep 01 '10 01:09

pierrotlefou


1 Answers

In Java, "returning and object" is actually semantically equivalent to returning a pointer to the object in C++, you are trying to return an object by value, which makes a copy of it. You can't make a copy of an abstract object.

So, while C++ may be more verbose, it supports different semantics for passing parameters and returning values, which Java doesn't support (return by value, pass by reference).

With that said, you should return by smart pointer, which does memory management for you. Others have pointed out auto_ptr with ownership transfer semantics, but you can also use boost::shared_ptr, in case you use custom memory allocation internally (e.g. a pool), shared_ptr's custom deleter feature will help you hide deallocation details from the user of the interface. It can also be used in STL containers (unlike auto_ptr).

class Car
{
public:
    typedef boost::shared_ptr<Car> Ptr;
    virtual int price() = 0 ;
    virtual string brand() = 0 ;
};

class Interface
{
public:
    virtual Car::Ptr giveMeACar() = 0 ;
    virtual vector<Car::Ptr> listMeAllTheCars() = 0 ;
}
like image 186
Alex B Avatar answered Sep 27 '22 19:09

Alex B