2014-12-14 2 views
-1

Мне просто интересно. Если производный класс использует наследование наследования для наследования из базового класса, а также переопределяет одну из функций открытого элемента базового класса, что использует компилятор, если экземпляр производного класса вызывает print(), например? И печать определена в базовом классе и переопределена в производном классе? Большое спасибо!!Что касается C++ Inheritance

ответ

3

Переопределяя функцию элемента базового класса в производном классе, новое определение скрывает старое определение.

Следовательно, в рамках производного класса можно увидеть только новое определение.

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; 
} 
+0

бы это изменение, если печать была объявлена ​​виртуальной, хотя в базовом классе? –

+0

Конечно. Если 'print' был виртуальным, вызов' print' из указателя вызывал соответствующую функцию 'print' на основе динамического типа указателя (т. Е. Типа фактического объекта, на который указывает указатель). 'pb-> print()' будет затем вызывать 'Derived :: print()'. – Nard

+0

Я понял. Спасибо!!! Это не повлияло бы на точечную нотацию, верно? Я проверил это, и это не так. Просто хочу убедиться. Еще раз спасибо <3 –

1

Компилятор использует статический тип объекта, который определяет, какую функцию вызывать. Любое имя, включая функции-члены, объявленные в производном классе, скрывает декларации с тем же именем в базовом классе.

Например

#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! 
+0

Спасибо, столько Влада! Быстрый вопрос. Сопротивлял ли компилятор char A и 0 как double? (для полученных) Спасибо! –

+0

@Kevin Cheng Функция-член в производном классе скрывает функции-члены в базовом классе с тем же именем. Поэтому они не принимают участия в разрешении перегрузки. –

Смежные вопросы