Я написал абстрактный класс (с чистыми виртуальными функциями) и хотел бы, чтобы метод принимал один такой класс в качестве параметра. Учитывая, что класс является абстрактным, я понимаю, что я не могу передать абстрактный класс любому методу, но почему я не могу передать подкласс абстрактного класса этому методу? Как указать, что параметр должен быть любым из подклассов указанного базового класса? Все это на C ++.
Передать абстрактный параметр в метод, почему бы и нет?
Ответы (3)
Вам необходимо указать параметр как указатель (или ссылку), например. Abstract *
, а не Abstract
. Если Derived
наследуется от Abstract
, вы можете передать переменную типа Derived *
, когда ожидается Abstract *
, но, как правило, вы не можете передать переменную типа Derived
, когда ожидается Abstract
.
Derived*
в Abstract*
и неявное преобразование из Derived&
в Abstract&
. Ни для того, ни другого не требуется.
- person Pete Becker; 07.12.2013
Abstract
по значению, она создаст копию переданного объекта. Вы не можете создать копию Abstract
, потому что она абстрактная. И даже если бы он не был абстрактным, копировалась бы только часть объекта базового класса. Передача по ссылке - это нормально, по сути, это то же самое, что передача по указателю, только с другим синтаксисом.
- person Taylor Brandstetter; 07.12.2013
Затем вы используете полиморфизм в C ++.
Учитывая любой базовый класс:
struct Base{};
и его подклассы:
struct SubClassA : public Base(){};
struct SubClassB : public Base(){};
Если вы заявляете:
void MyFunctionReference(Base&){};
void MyFunctionPointer(Base*){};
Затем вы можете позвонить:
{
SubClassA a;
SubClassB b;
MyFunctionReference(a); // by reference
MyFunctionPointer(&b); // by pointer address
}
Вы действительно можете это сделать, обратите внимание:
Чистый абстрактный класс:
class Abstract {
public:
virtual void foo() = 0;
};
Дочерний элемент переопределения функции-члена:
class AbstractImpl : public Abstract {
public:
void foo() override { std::cout << "Hi from subclass\n"; }
};
Теперь мы объявляем метод, который принимает ссылочный тип абстрактного класса
void somefunc(Abstract &ab) {
ab.foo();
}
Наконец, в основном мы создаем экземпляр параметра дочернего класса
int main() {
AbstractImpl test;
somefunc(test); // prints Hi from subclass
return 0;
}
Источник: https://stackoverflow.com/a/11422101/2089675