《C++语言教程》09章 派生类中调用基类成员


一、基类和派生类具有相同成员时

第7章中已经说明了一旦继承之后,派生类就具有了基类的公有成员和保护成员,可以直接使用,在外部也可直接访问基类的公有成员。这一章要讲解的是如果基类和派生类具有相同名称的成员变量或可以成员函数时,如何区别使用。

下面例子中,基类和派生类都有成员变量“id”和成员函数“show()”,无论是在派生类的内部还是外部,直接调用的成员都是派生类的成员,而基类的成员函数show()未被调用。要调用基类成员,必须在成员函数名前加上范围(类名::),这也适用于基类的成员变量。


#include <iostream>
#include <string>
using namespace std;

class CBase {
    string id;
    string name;
public:
    CBase(string s1, string s2) : name(s1), id("base-"+s2) { }
    void show() {
        cout << "name: " << name << endl;
        cout << "id: " << id << endl;
    }
};

class CDerive : public CBase {
    string id;
    int age;
public:
    CDerive(string s1, int a, string s2) : age(a), id("DERIVE-"+s2), CBase(s1, s2) { }
    void show() {
        cout << "id: " << id << endl;
        cout << "age: " << age << endl;

        //派生类的内部调用基类的方法
        CBase::show();
        //show();    //如果误写成这样,将不断地重复循环地调用自身(即死循环)。
    }
};

int main ( ) 
{
    CDerive d("小雅", 27, "8503026");    //派生类的实例
    d.show();    //运行的是CDerive类的show()函数
    cout << "-------------"<< endl;

    //类的外部调用基类的方法
    d.CBase::show();    //运行的是CBase类的show()函数
    cout << "-------------"<< endl;

    CBase b("小雅", "8503026");    //基类当作普通类直接产生的实例
    b.show();    //运行的是CBase类的show()函数

    return 0;
}

二、多重继承的调用方法

多重继承时参数的调用方法和上面一样,只要在函数名前加上范围,调用成员变量也是一样。注意:要调用基类的成员变量时,要修改一下访问权限,不能为“private”。


#include <iostream>
#include <string>
using namespace std;

class CBase1 {
    string name;
protected:
    string id;
public:
    CBase1(string s1, string s2) : name(s1), id("base1-"+s2) { }
    void show() {
        cout << "name: " << name << endl;
        cout << "id: " << id << endl;
    }
};

class CBase2 {
    int salary;
protected:
    string id;
public:
    CBase2(int y, string s2) : salary(y), id("base2-"+s2) { }
    void show() {
        cout << "salary: " << salary << endl;
        cout << "id: " << id << endl;
    }
};

class CDerive : public CBase1, public CBase2 {
    string id;
    int age;
public:
    CDerive(string s1, int a, string s2, int y) 
        : age(a), id("DERIVE-"+s2), CBase1(s1, s2), CBase2(y, s2) { }
    void show() {
        cout << "id: " << id << endl;
        cout << "age: " << age << endl;
        CBase1::show();
        CBase2::show();
        cout << "bas1: " << CBase1::id << endl;  //调用CBase1的成员变量
        cout << "bas2: " << CBase2::id << endl;  //调用CBase2的成员变量
    }
};

int main ( ) 
{
    CDerive d("小雅", 27, "8503026", 5000);
    d.show();

    return 0;
}

三、删除派生类中的同名函数

上一个例子中,如果修改2个基类的show()函数的参数,在派生类或外部也一样不能直接调用,必须加上范围。下面,我们将派生类中的同名函数show()删除,是否会出错呢?


#include <iostream>
#include <string>
using namespace std;

class CBase1 {
    string name;
    string id;
public:
    CBase1(string s1, string s2) : name(s1), id("base1-"+s2) { }
    void show() {
        cout << "name: " << name << endl;
        cout << "id: " << id << endl;
    }
};

class CBase2 {
    int salary;
    string id;
public:
    CBase2(int y, string s2) : salary(y), id("base2-"+s2) { }
    void show() {
        cout << "salary: " << salary << endl;
        cout << "id: " << id << endl;
    }
};

class CDerive : public CBase1, public CBase2 {
    string id;
    int age;
public:
    CDerive(string s1, int a, string s2, int y) 
        : age(a), id("DERIVE-"+s2), CBase1(s1, s2), CBase2(y, s2) { }
};

int main ( ) 
{
    CDerive d("小雅", 27, "8503026", 5000);
    //d.show();    //编译出错,不知从哪个基类继承。
    d.CBase1::show();
    d.CBase2::show();

    return 0;
}