2015-03-13 3 views
1

Я столкнулся со следующей ситуацией:Как обрабатывать возвращение абстрактных объектов

class Base{ 
     virtual void Stuff() = 0; 
}; 

class ConcreteA : public Base{ 
     void Stuff() {}; 
}; 

class ConcreteB : public Base{ 
     void Stuff() {}; 
}; 

class Context { 
     Base exec() { 
      ConcreteA conc_a(); 
      return a; 
     } 
}; 

Конечно компилятор дает мне ошибку, так как Base является абстрактным. Однако мне нужно, чтобы exec() возвращал базовый тип. Я знаю, что могу сделать компилятор счастливым с помощью указателей или ссылок, но поскольку объект ConcreteA создается в exec(), возврат по значению - лучший способ избежать оборванных ссылок или указателя с неопределенным правом собственности.

Есть ли способ избежать использования указателей или ссылок для обработки таких ситуаций?

+0

Нет никакого способа избежать ссылок или указателей, если вы хотите вернуть «базовый» тип. –

+0

'std :: unique_ptr'? –

ответ

3

Это выглядит как идеальный, простой вариант использования для std::unique_ptr. Вот C++ 14 Пример:

#include <memory> 
#include <iostream> 

class Base{ 
public: 
     virtual ~Base() {} 
     virtual void Stuff() = 0; 
}; 

class ConcreteA : public Base{ 
     void Stuff() { std::cout << "ConcreteA::Stuff\n"; }; 
}; 

class ConcreteB : public Base{ 
     void Stuff() { std::cout << "ConcreteB::Stuff\n";}; 
}; 

class Context { 
public: 
     std::unique_ptr<Base> exec() { 
      return std::make_unique<ConcreteA>(); 
     } 
}; 

int main() 
{ 
    Context c; 
    auto base_ptr = c.exec(); 
    base_ptr->Stuff(); 
} 

памяти автоматически удаляется при base_ptr в main выходит из области видимости.

Обратите внимание, что я также создал виртуальный виртуальный дескриптор Base. Возможно, вы просто оставили это в своем примере кода ради краткости, но его важность должна быть подчеркнута, и я думаю, что его нужно держать даже в коротком примере кода.

+0

Возможно, стоит обратить внимание на важность добавления виртуального деструктора. –

+0

@MikeSeymour: Верно. Я добавил что-то к ответу. –

+0

@Mike Seymour Что вы имеете в виду? Уникальный_ptr должен быть автоматически удален, когда Context выходит из области видимости, я ошибаюсь? – gcswoosh

Смежные вопросы