Мне просто интересно. Если производный класс использует наследование наследования для наследования из базового класса, а также переопределяет одну из функций открытого элемента базового класса, что использует компилятор, если экземпляр производного класса вызывает print(), например? И печать определена в базовом классе и переопределена в производном классе? Большое спасибо!!Что касается C++ Inheritance
ответ
Переопределяя функцию элемента базового класса в производном классе, новое определение скрывает старое определение.
Следовательно, в рамках производного класса можно увидеть только новое определение.
class Base
{
public:
void print() { std::cout << "b \n"; }
};
class Derived : public Base
{
public:
void print() { std::cout << "d \n"; }
};
int main(void)
{
Base b;
Derived d;
Base *pb = &d;
Derived *pd = &d;
b.print(); // Calls Base::print()
d.print(); // Calls Derived::print()
pb->print(); // Calls Base::print()
pd->print(); // Calls Derived::print()
getchar();
return 0;
}
Компилятор использует статический тип объекта, который определяет, какую функцию вызывать. Любое имя, включая функции-члены, объявленные в производном классе, скрывает декларации с тем же именем в базовом классе.
Например
#include <iostream>
#include <string>
class Base
{
public:
Base() : data(10) {}
void f(char) { std::cout << "Base::f(char)" << std::endl; }
void f(int) { std::cout << "Base::f(int)" << std::endl; }
int data;
};
class Derived : public Base
{
public:
Derived() : data("Hello World!") {}
void f(double) { std::cout << "Derived::f(double)" << std::endl; }
std::string data;
};
int main()
{
Base b;
b.f(0);
b.f('A');
std::cout << b.data << std::endl;
std::cout << std::endl;
Derived d;
d.f(0);
d.f('A');
std::cout << d.data << std::endl;
std::cout << std::endl;
Base *pb = new Derived;
pb->f(0);
pb->f('A');
std::cout << pb->data << std::endl;
delete pb;
return 0;
}
Выход программы
Base::f(int)
Base::f(char)
10
Derived::f(double)
Derived::f(double)
Hello World!
Base::f(int)
Base::f(char)
10
Используя виртуальные функции вместо невиртуальном обеспечивает полиморфизм.
Например
#include <iostream>
#include <string>
class Base
{
public:
Base() : data(10) {}
virtual ~Base() {}
virtual void print() const { std::cout << data << std::endl; }
int data;
};
class Derived : public Base
{
public:
Derived() : data("Hello World!") {}
void print() const
{
Base::print();
std::cout << data << std::endl;
}
std::string data;
};
int main()
{
Base b;
b.print();
std::cout << std::endl;
Derived d;
d.print();
std::cout << std::endl;
Base *pb = new Derived;
pb->print();
delete pb;
return 0;
}
Выход программы
10
10
Hello World!
10
Hello World!
Спасибо, столько Влада! Быстрый вопрос. Сопротивлял ли компилятор char A и 0 как double? (для полученных) Спасибо! –
@Kevin Cheng Функция-член в производном классе скрывает функции-члены в базовом классе с тем же именем. Поэтому они не принимают участия в разрешении перегрузки. –
- 1. Что касается Inheritance C#
- 2. Что касается чтения C# Xml
- 3. Что касается C ЬурейиХ структуры
- 4. Что касается использования ManualResetEvent C#?
- 5. Что касается Stringbuilder в C#
- 6. C Выпуск Что касается деклараций
- 7. Что касается реентерации в C
- 8. Что касается C# OOPS использования
- 9. Что касается шаблонов в C++
- 10. Что касается списков в C++
- 11. Что касается FOPEN в C
- 12. C# list inheritance
- 13. Что касается *?
- 14. Что касается try-catch
- 15. Что касается соответствия подстроки
- 16. Что касается синтаксического сахара
- 17. Что касается репликации sqlite
- 18. Что касается контейнера STL
- 19. Что касается копирования объектов
- 20. C++ Что касается указателя/ссылки с remove_if
- 21. Что касается примитивных типов данных в C#
- 22. Что касается программирования Windows с использованием C++
- 23. Что касается I ++ и ++ я в C++
- 24. Что касается регулярного выражения в C#
- 25. Что касается шаблонов для структуры в C++
- 26. Что касается арифметики указателя в C
- 27. Что касается простого наследования в C#
- 28. Что касается управления памятью в Objective C
- 29. Что касается синтаксиса в C# и VB
- 30. Что касается разрешения на файл в C#
бы это изменение, если печать была объявлена виртуальной, хотя в базовом классе? –
Конечно. Если 'print' был виртуальным, вызов' print' из указателя вызывал соответствующую функцию 'print' на основе динамического типа указателя (т. Е. Типа фактического объекта, на который указывает указатель). 'pb-> print()' будет затем вызывать 'Derived :: print()'. – Nard
Я понял. Спасибо!!! Это не повлияло бы на точечную нотацию, верно? Я проверил это, и это не так. Просто хочу убедиться. Еще раз спасибо <3 –