Как вызвать функцию родительского класса из функции производного класса?
Как вызвать функцию родительского класса из производного класса на C++? У меня есть класс под названием parent
и класс child
, который наследуется от parent
. В каждом классе есть функция print
. В определении функции print
класса child
я хотел бы вызвать функцию print
родительского класса. Как мне это сделать?
5 ответ(ов)
Ваша реализация выглядит хорошо, но есть несколько моментов, которые стоит уточнить, чтобы обеспечить более полное понимание.
Вы объявили родительский класс Parent
с виртуальным методом print
, который может быть переопределён в дочернем классе Child
. Вот как это выглядит:
class Parent {
public:
virtual void print(int x);
};
class Child : public Parent {
void print(int x) override;
};
void Parent::print(int x) {
// некоторая стандартная логика
}
void Child::print(int x) {
// вызывает метод print родительского класса; 'this' передаётся неявно
Parent::print(x);
}
В этом коде метод print
в классе Child
вызывает реализацию метода print
из родительского класса Parent
. Это делается с помощью синтаксиса Parent::print(x);
, который позволяет использовать логику родительского метода, если это необходимо в дочернем классе.
Также, имя Parent
в данном случае является именем класса, а не зарезервированным словом, что делает ваш код правильно структурированным. После выполнения данного кода, если создать объект класса Child
и вызвать метод print
, сначала будет выполнена логика родительского класса, а затем можно добавить специфичную для дочернего класса логику.
Если у вас есть дополнительные вопросы о виртуальных методах и наследовании в C++, не стесняйтесь спрашивать!
Чтобы вызвать метод FooBar()
из базового класса Base
в производном классе ChildOfBase
, вы можете использовать синтаксис Base::FooBar()
. Вот пример кода:
void Base::FooBar()
{
printf("in Base\n");
}
void ChildOfBase::FooBar()
{
Base::FooBar(); // Вызов метода FooBar() из базового класса
}
В данном примере метод FooBar()
базового класса Base
будет выполнен при вызове ChildOfBase::FooBar()
, что означает, что на экран будет выведено "in Base". Это позволяет перегружать методы в производном классе, при этом сохраняя возможность вызывать их реализации из базового класса.
В MSVC существует специфическое для Microsoft ключевое слово для этого: __super.
Согласно документации MSDN: Позволяет вам явно указать, что вы вызываете реализацию метода базового класса для функции, которую вы переопределяете.
// deriv_super.cpp
// компилируйте с: /c
struct B1 {
void mf(int) {}
};
struct B2 {
void mf(short) {}
void mf(char) {}
};
struct D : B1, B2 {
void mf(short) {
__super::mf(1); // Вызывает B1::mf(int)
__super::mf('s'); // Вызывает B2::mf(char)
}
};
Чтобы вызвать метод родительского класса с использованием оператора разрешения области видимости (scope resolution operator), вы можете использовать следующий синтаксис:
Parent::method()
В вашем примере, чтобы вызвать метод whatAmI
из класса Primate
внутри класса Human
, вы можете сделать это следующим образом:
class Primate {
public:
void whatAmI(){
cout << "I am of Primate order";
}
};
class Human : public Primate{
public:
void whatAmI(){
cout << "I am of Human species";
}
void whatIsMyOrder(){
Primate::whatAmI(); // <-- Оператор разрешения области видимости
}
};
Здесь в методе whatIsMyOrder
мы используем Primate::whatAmI()
, чтобы вызвать метод whatAmI
из родительского класса Primate
, игнорируя реализацию этого метода в классе Human
. Это полезный прием, когда вам нужно обратиться к функции родителя, несмотря на его переопределение в дочернем классе.
Если модификатор доступа член-функции базового класса является protected или public, вы можете вызывать члены базового класса из производного класса. Обратите внимание, что как виртуальные, так и не виртуальные функции базового класса могут быть вызваны из функций производного класса.
Ниже представлен пример программы, которая демонстрирует это:
#include<iostream>
using namespace std;
class Parent
{
protected:
virtual void fun(int i)
{
cout<<"Parent::fun functionality write here"<<endl;
}
void fun1(int i)
{
cout<<"Parent::fun1 functionality write here"<<endl;
}
void fun2()
{
cout<<"Parent::fun3 functionality write here"<<endl;
}
};
class Child:public Parent
{
public:
virtual void fun(int i)
{
cout<<"Child::fun partial functionality write here"<<endl;
Parent::fun(++i); // Вызов виртуальной функции базового класса
Parent::fun2(); // Вызов не виртуальной функции базового класса
}
void fun1(int i)
{
cout<<"Child::fun1 partial functionality write here"<<endl;
Parent::fun1(++i); // Вызов не виртуальной функции базового класса
}
};
int main()
{
Child d1;
d1.fun(1); // Вызов функции Child
d1.fun1(2); // Вызов функции Child
return 0;
}
При выполнении программы вывод будет следующим:
$ g++ base_function_call_from_derived.cpp
$ ./a.out
Child::fun partial functionality write here
Parent::fun functionality write here
Parent::fun3 functionality write here
Child::fun1 partial functionality write here
Parent::fun1 functionality write here
Таким образом, как видно из примера, функции базового класса могут быть успешно вызваны из производного класса, что подтверждает утверждение о доступности Protected и Public членов.
Понимание Python super() с методами __init__()
Почему классы в Python наследуют от object?
Какова разница между публичным, приватным и защищённым наследованием?
Каковы правила вызова конструктора базового класса?
Как удалить элемент из std::vector<> по индексу?