Возможно ли вернуть абстрактный объект (класс или ссылку, не имеет значения) из функции?Возвращение абстрактного класса из функции
ответ
Вы можете вернуть абстрактный указатель класса - при условии, B
это конкретный класс, производный от абстрактного класса A
:
A * f() {
return new B;
}
или ссылка:
A & f() {
static B b;
return b;
}
или смарт-указатель:
std::unique_ptr<A> f() {
return std::make_unique<B>(...);
}
Абстрактные классы не могут быть созданы и, следовательно, не возвращены.
Как насчет ссылки? Я знаю, что невозможно передать абстрактный класс в качестве параметра функции, но я могу передать ссылку абстрактного класса. – cemregoksu
Только если ссылки фактически ссылаются на экземпляр дочернего класса. –
ну, а как насчет этого сценария? класс A { виртуальный void f() = 0; }; void fonk (A & a) {} работает. , так можно ли сформировать функцию, чтобы снова вернуть ссылку класса? – cemregoksu
Нет, но функция может иметь возвращаемый тип указателя (или ссылки) для абстрактного класса. Затем он будет возвращать экземпляры класса, полученного из абстрактного класса.
Вы имеете в виду «возвращаемый тип * ссылки на * абстрактный класс». – avakar
Я не мог понять, что вы имеете в виду. можете ли вы привести небольшой пример? – cemregoksu
@incrediman: тогда он ошибается. – avakar
Вы можете объявить тип возвращаемого значения как ссылку или указатель на абстрактный класс, чтобы он мог быть привязан к ссылкам или указателям на абстрактный класс и использоваться на основе его интерфейса.
Тем не менее, вы не можете вернуть фактический экземпляр фактического абстрактного класса, потому что по определению вы не можете его создать. Однако вы могли возвращать экземпляры конкретных подтипов, которые достаточно хороши, потому что в principle of substitution вы всегда должны использовать подтип вместо супертипа.
Фабрика шаблон проектирования является примером возвращающая указатель на абстрактный объект класса:
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;
}
Фактический абстрактный объект базового класса никогда не могут быть возвращены, так как никогда не может быть экземпляр абстрактного базового класса. Указатели и ссылки на абстрактный базовый тип могут быть возвращены, как в приведенном выше примере.
Указатели и ссылки на абстрактный базовый класс, возвращаемый функцией или методом, фактически относятся к потомку абстрактного базового типа.
Я знаю, что я немного поздно, но я надеюсь, что это поможет кому-то ...
Будучи новичком в C++ программирование, я тоже застрял на некоторое время на эту проблему. Я хотел создать фабричный метод, который возвращает ссылку на абстрактный объект. Мое первое решение с использованием указателей хорошо работало, но я хотел остановиться на более «манере C++». Вот фрагмент кода, который я написал, чтобы продемонстрировать это:
#include <iostream>
using std::cout;
using std::endl;
class Abstract{
public:
virtual void foo() = 0;
};
class FirstFoo: public Abstract{
void foo()
{
cout << "Let's 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;
}
}
Открыт для любого критика!
'factoryMethod' теряет память каждый раз, когда вы его вызываете. Результат распределяется по куче, но он никогда не удаляется. (Вызывающий не может удалить его, потому что вместо ссылки указывается ссылка.) –
В C++ 11 работает std :: unique_ptr. – user877329
Я согласен с проблемой утечки памяти, но я только что научился импортировать определенные символы из пространства имен, используя 'using', я знал только об использовании пространства имен до сих пор! Спасибо за это @morandg! – stakx
- 1. Возвращение класса реф из функции
- 2. Вызов абстрактного метода из родительского абстрактного класса
- 3. Scala: Возвращение типа абстрактного метода
- 4. Реализация компаратора из абстрактного класса
- 5. Наследовать аннотации из абстрактного класса?
- 6. Usercontrol, полученный из абстрактного класса
- 7. Получить переменную из абстрактного класса
- 8. Извлечение данных из абстрактного класса
- 9. Переходя метод абстрактного класса, как станд :: функции
- 10. Получение класса из абстрактного класса (C++)
- 11. Получение типа абстрактного базового класса из класса
- 12. Метод абстрактного класса вызова из имени класса
- 13. Возвращение родового объекта на Java от абстрактного класса
- 14. Обозначение функции для подклассов абстрактного класса
- 15. Функции C++ для абстрактного базового класса
- 16. Ошибка компиляции для абстрактного класса/функции
- 17. Возвращение «c_str» из функции
- 18. возвращение итератора из функции
- 19. Возвращение массива из функции
- 20. Возвращение массива из функции
- 21. Возвращение CGPoints из функции
- 22. Возвращение namedtuple из функции
- 23. возвращение shared_ptr из функции
- 24. Возвращение из пустоты функции
- 25. Возвращение переменной из функции
- 26. Возвращение массива из общего класса
- 27. вызова абстрактный метод из абстрактного класса конструктора
- 28. js создания абстрактного класса
- 29. создать объект абстрактного класса! = Создать экземпляр абстрактного класса?
- 30. C - Возвращение массива из функции
Я хочу использовать сам абстрактный класс (или его ссылку), чтобы использовать его как общую форму для других классов, которые получены из этого абстрактного класса. – cemregoksu
@cemregoksu Это единственная цель для абстрактного класс. Обе приведенные выше функции иллюстрируют, как вы это сделаете в отношении возвращаемых значений функции. – 2010-05-18 21:39:34
благодарит за вашу помощь. я думаю, что он работал =) – cemregoksu