2013-12-06 3 views
3

Я написал абстрактный класс (с чистыми виртуальными функциями), и я хотел бы, чтобы метод принимал один такой класс, как параметр. Учитывая, что класс является абстрактным, я понимаю, что я не мог передать абстрактный класс любому методу, но почему я не могу передать подкласс абстрактного класса этому методу? Как указать, что параметр должен быть любым из подклассов заданного базового класса? Это все на C++.Передайте абстрактный параметр методу, почему бы и нет?

+0

Это половина смысла использования наследования. Просто попросите метод взять указатель на абстрактный класс, тогда вы можете передать ему указатель на любой производный класс. –

+1

«Учитывая, что класс является абстрактным, я понимаю, что я не мог передать абстрактный класс любому методу». Это верно ** только **, если вы ограничиваете себя передачей по значению. В общем, используйте полиморфизм (передайте по ссылке или пройдите по адресу указателя) при работе с абстрактным и, в более общем смысле, базовым/материнским классом. –

ответ

3

Необходимо указать параметр в качестве указателя (или ссылки), например. Abstract *, а не Abstract. Если Derived наследует от Abstract, вы можете передать переменную типа Derived *, когда ожидается Abstract *, но вы не можете в общем пройти один из типов Derived, когда ожидается Abstract.

+0

В чем причина этого? Какой смысл ограничивать использование параметров? – Jack

+0

@Jack Потому что вы не можете создать экземпляр абстрактного класса. – smac89

+0

@ Smac89 - даже если бы вы могли, передав его по значению, ** нарезал ** объект. –

0

Вы действительно можете сделать это, заметим:

чисто абстрактный класс:

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

1

Затем вы используете полиморфизм в 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 
} 
Смежные вопросы