Возврат абстрактного класса из функции
Можно ли вернуть абстрактный объект (класс или ссылку, не имеет значения) из функции?
Ответы
Ответ 1
Вы можете вернуть абстрактный указатель класса - если B
- это конкретный класс, полученный из абстрактного класса A
:
A * f() {
return new B;
}
или ссылка:
A & f() {
static B b;
return b;
}
или умный указатель:
std::unique_ptr<A> f() {
return std::make_unique<B>(...);
}
Ответ 2
Вы можете объявить возвращаемый тип ссылкой или указателем на абстрактный класс, чтобы его можно было присвоить ссылкам или указателям на абстрактный класс и использовать на основе его интерфейса.
Однако вы не можете вернуть фактический экземпляр фактического абстрактного класса, потому что по определению вы не можете его создать. Однако вы могли возвращать экземпляры конкретных подтипов, которые достаточно хороши, потому что в принципе замещения вы всегда должны использовать подтип супертипа.
Ответ 3
Нет, но функция может иметь возвращаемый тип указателя (или ссылки) для абстрактного класса. Затем он будет возвращать экземпляры класса, полученного из абстрактного класса.
Ответ 4
Абстрактные классы не могут быть созданы и, следовательно, не возвращены.
Ответ 5
Шаблон проектирования Factory является примером возврата указателя на абстрактный объект класса:
class Base
{ ; }
class One : public Base
{ ; }
class Two : public Base
{ ; }
Base * Factory(unsigned int number)
{
Base * p_item(NULL);
switch (number)
{
case 1:
p_item = new One;
break;
case 2:
p_item = new Two;
break;
default:
p_item = NULL;
break;
}
return p_item;
}
Фактический объект абстрактного базового класса никогда не может быть возвращен, поскольку никогда не может быть экземпляром абстрактного базового класса. Указатели и ссылки на абстрактный базовый тип могут быть возвращены, как в приведенном выше примере.
Указатели и ссылки на абстрактный базовый класс, возвращаемые функцией или методом, фактически ссылаются на потомка абстрактного базового типа.
Ответ 6
Я знаю, что немного опаздываю, но надеюсь, что это поможет кому-то...
Будучи новичком в программировании на C++, я тоже некоторое время задерживался на этой проблеме. Я хотел создать метод factory, который возвращает ссылку на абстрактный объект. Мое первое решение с использованием указателей хорошо работало, но я хотел остановиться на более "манере С++". Вот фрагмент кода, который я написал, чтобы продемонстрировать его:
#include <iostream>
using std::cout;
using std::endl;
class Abstract{
public:
virtual void foo() = 0;
};
class FirstFoo: public Abstract{
void foo()
{
cout << "Let go to the foo bar!" << endl;
}
};
class SecondFoo: public Abstract{
void foo()
{
cout << "I prefer the foo beer !" << endl;
}
};
Abstract& factoryMethod(){
static int what = 0;
if(what++ % 2 == 0)
return *(new FirstFoo());
else
return *(new SecondFoo());
}
int main(int argc, char* argv[])
{
int howMany = 10;
int i = 0;
while(i++ < howMany)
{
Abstract& abs = factoryMethod();
abs.foo();
delete &abs;
}
}
Откройте любую критику!