📜  C++ |继承|问题13(1)

📅  最后修改于: 2023-12-03 14:39:54.217000             🧑  作者: Mango

C++ | 继承 | 问题13

在C++中,继承是一种重要的面向对象编程的特性。通过继承,一个类可以从另一个类继承属性和方法。在继承过程中,派生类可以拥有基类的所有属性和方法,同时还可以添加自己的属性和方法。通常情况下,基类的属性和方法都是可以被派生类访问和使用的。本文将介绍C++继承中的一个问题,以及如何处理。

问题

考虑一个基类Person和派生类Student的情况,Student继承了Person的所有属性和方法。现在要求Student类具有一个新的成员函数getName(),这个函数返回Student类的姓名。代码如下所示:

class Person {
protected:
    string name;
    int age;
public:
    Person(string n, int a) : name(n), age(a) {}
    void display() {
        cout << "Name: " << name << endl;
        cout << "Age: " << age << endl;
    }
};

class Student : public Person {
public:
    Student(string n, int a) : Person(n, a) {}
    void getName() {
        cout << "Name: " << name << endl;
    }
};

main()函数中,我们可以使用Person类的display()函数来显示一个人的姓名和年龄:

Person p("John", 20);
p.display(); // Name: John Age: 20

同样,对于一个Student类的对象,我们也可以使用display()函数来显示学生的姓名和年龄:

Student s("Mike", 18);
s.display(); // Name: Mike Age: 18

但是,现在我们需要使用getName()函数来获取学生的姓名:

Student s("Mike", 18);
s.getName(); // Name: Mike

但是上述代码执行时无法通过编译。该怎么办呢?

解决方案

出现上述错误的原因是,派生类Student中没有定义name属性,所以无法访问基类Person中的name属性。解决这个问题的方法有两个:一是将name属性定义在Student类中,二是将基类Person中的属性nameprotected改为public

方法一

Student类中添加name属性:

class Student : public Person {
private:
    string name;
public:
    Student(string n, int a) : Person(n, a), name(n) {}
    void getName() {
        cout << "Name: " << name << endl;
    }
};

通过上面的改动,我们新增了一个privatename属性,该属性与基类Person中的name属性没有任何关系。

方法二

将基类中的name属性改为public

class Person {
public:
    string name;
    int age;
    Person(string n, int a) : name(n), age(a) {}
    void display() {
        cout << "Name: " << name << endl;
        cout << "Age: " << age << endl;
    }
};

class Student : public Person {
public:
    Student(string n, int a) : Person(n, a) {}
    void getName() {
        cout << "Name: " << name << endl;
    }
};

通过上面的改动,我们将基类中的name属性从protected改为public,这样派生类就可以自由的访问该属性了。

总结

本文介绍了C++继承中的一个问题,即在派生类中访问基类中的属性时编译错误的解决方法。这个问题的根本原因是派生类中没有定义基类中的属性,需要通过新增属性或者改变属性的访问权限来解决问题。在C++的继承中,基类的属性和方法都是可以被派生类访问和使用的,不仅可以继承,还可以扩展,具有很大的灵活性。