Я хотел бы вернуть объект виртуального базового класса, чтобы мне не приходилось иметь дело с управлением памятью (идея функционального программирования также стимулирует это стремление). Это означает, что я ищу такие вещи, как показано ниже:
class Car
{
public:
virtual int price() = 0 ;
virtual string brand() = 0 ;
}
class Interface
{
public:
virtual Car giveMeACar() = 0 ;
virtual vector<Car> listMeAllTheCars() = 0 ;
}
Однако это даже не скомпилируется, потому что Car является абстрактным интерфейсом с сообщением об ошибке:
функция-член ' виртуальный автомобиль
giveMeACar () = 0
; поскольку
следующие виртуальные функции являются чистыми
в ' Автомобиль
': int price ()
string brand ()
;
Значит ли это, что я должен изменить интерфейс, чтобы что-то вроде ниже и сам управляю памятью (удаляйте экземпляр после его использования) - исключая возможность использования интеллектуального указателя.
class Interface
{
public:
virtual Car* giveMeACar() = 0 ;
virtual vector<Car*> listMeAllTheCars() = 0 ;
}
У меня вопрос: это единственный вариант, который у меня есть при разработке интерфейса, в котором все элементы (классы) абстрактны?
Возврат объекта класса интерфейса идеально подходит для Java. C ++ кажется немного многословным и противоречит интуиции в этом аспекте. Чаще мне кажется, что C ++ - это «указатель на язык объектного программирования», а не «язык объектного программирования», потому что без указателя вы не сможете получить слишком много преимуществ от объектного программирования.
Вернуть std::auto_ptr
. Он помещает объект в кучу, как указатель, но удаляет его, когда он выходит за пределы области видимости, как переменную стека.
Варианты включают boost::unique_ptr
и C++0x std::unique_ptr
, который заменяет auto_ptr
.
vector
нельзя заменить на vector< auto_ptr< Car > >
, поскольку auto_ptr
несовместим с контейнерами. Для этого вам нужно использовать unique_ptr
.
Ваши наблюдения верны, нет простого способа сделать то, что вы хотите сделать. В C++ вы не можете вернуть Car по значению, потому что (среди прочего) вызывающему объекту необходимо выделить для него место.
Java принципиально не отличается, просто его синтаксис не может выразить то, что вы хотите выразить — все типы (кроме примитивных типов) имеют неявно присоединенный к ним символ «*». И у него есть сборка мусора, поэтому вам не нужно беспокоиться об управлении памятью.
Другие сообщения в ответ на ваш запрос полностью отвечают на ваш запрос. Однако у меня есть несколько наблюдений, которые вы можете принять во внимание.
Первое наблюдение:
Избегайте раскрытия деталей реализации внешнему миру.
Это относится к возвращаемому типу
virtual vector
.
Почему пользователи class должны знать, используете ли вы vector
или list
или что-то еще? Ознакомьтесь с шаблоном проектирования итератора от GOF. C++ имеет хорошую поддержку итераторов.
Второе наблюдение:
Ваше требование, кажется, имитирует потребность в шаблоне проектирования Factory Method, особенно когда я смотрю на
virtual Car giveMeACar() = 0 ;
Возможно, вы захотите взглянуть на шаблон проектирования фабричного метода.
Третье наблюдение:
Однако наличие обеих этих функций в одном интерфейсе не кажется мне неуместным. Вы можете рассмотреть дизайн еще раз. Придерживайтесь принципа единой ответственности.