继承是C++ 面向对象编程的关键特性之一。它允许我们从现有类(基类)创建一个新类(派生类)。
派生类继承了基类的特性,并且可以拥有自己的附加特性。例如,
class Animal {
// eat() function
// sleep() function
};
class Dog : public Animal {
// bark() function
};
在这里,Dog
类是从 Animal
类派生而来的。由于 Dog
是从 Animal
派生而来的,因此 Animal
的成员可以被 Dog
访问。

请注意,在将 Dog 从 Animal 继承时使用了 public
关键字。
class Dog : public Animal {...};
我们也可以使用 private
和 protected
关键字来代替 public
。我们将在本教程后面学习使用 private
、public
和 protected
之间的区别。
is-a 关系
继承是一种“is-a”关系。只有当两个类之间存在“is-a”关系时,我们才使用继承。
以下是一些例子
- 汽车是一种交通工具。
- 橘子是一种水果。
- 外科医生是一名医生。
- 狗是一种动物。
示例 1:C++ 继承的简单示例
// C++ program to demonstrate inheritance
#include <iostream>
using namespace std;
// base class
class Animal {
public:
void eat() {
cout << "I can eat!" << endl;
}
void sleep() {
cout << "I can sleep!" << endl;
}
};
// derived class
class Dog : public Animal {
public:
void bark() {
cout << "I can bark! Woof woof!!" << endl;
}
};
int main() {
// Create object of the Dog class
Dog dog1;
// Calling members of the base class
dog1.eat();
dog1.sleep();
// Calling member of the derived class
dog1.bark();
return 0;
}
输出
I can eat! I can sleep! I can bark! Woof woof!!
在这里,dog1(派生类 Dog
的对象)可以访问基类 Animal
的成员。这是因为 Dog
是从 Animal
继承的。
// Calling members of the Animal class
dog1.eat();
dog1.sleep();
C++ protected 成员
访问修饰符 protected
在 C++ 继承中尤其重要。
与 private
成员一样,protected
成员在类外部是不可访问的。但是,它们可以被派生类和友元类/函数访问。
如果我们想隐藏一个类的私有数据,但又希望其派生类能够继承这些数据,那么我们就需要 protected
成员。
要了解更多关于 protected 的信息,请参考我们的 C++ 访问修饰符教程。
示例 2:C++ protected 成员
// C++ program to demonstrate protected members
#include <iostream>
#include <string>
using namespace std;
// base class
class Animal {
private:
string color;
protected:
string type;
public:
void eat() {
cout << "I can eat!" << endl;
}
void sleep() {
cout << "I can sleep!" << endl;
}
void setColor(string clr) {
color = clr;
}
string getColor() {
return color;
}
};
// derived class
class Dog : public Animal {
public:
void setType(string tp) {
type = tp;
}
void displayInfo(string c) {
cout << "I am a " << type << endl;
cout << "My color is " << c << endl;
}
void bark() {
cout << "I can bark! Woof woof!!" << endl;
}
};
int main() {
// Create object of the Dog class
Dog dog1;
// Calling members of the base class
dog1.eat();
dog1.sleep();
dog1.setColor("black");
// Calling member of the derived class
dog1.bark();
dog1.setType("mammal");
// Using getColor() of dog1 as argument
// getColor() returns string data
dog1.displayInfo(dog1.getColor());
return 0;
}
输出
I can eat! I can sleep! I can bark! Woof woof!! I am a mammal My color is black
在这里,变量 type 是 protected
的,因此可以从派生类 Dog
访问。我们可以看到,我们在 Dog
类中使用 函数 setType()
初始化了 type
。
另一方面,private
变量 color 不能在 Dog
中初始化。
class Dog : public Animal {
public:
void setColor(string clr) {
// Error: member "Animal::color" is inaccessible
color = clr;
}
};
此外,由于 protected
关键字会隐藏数据,我们无法直接从 Dog
或 Animal
类的对象访问 type。
// Error: member "Animal::type" is inaccessible
dog1.type = "mammal";
C++ 继承中的访问模式
在之前的教程中,我们已经学习了 C++ 的访问说明符,如 public、private 和 protected。
到目前为止,我们使用 public
关键字来从先前存在的基类继承一个类。但是,我们也可以使用 private
和 protected
关键字来继承类。例如,
class Animal {
// code
};
class Dog : private Animal {
// code
};
class Cat : protected Animal {
// code
};
我们可以派生类的各种方式被称为访问模式。这些访问模式具有以下效果:
- public: 如果一个派生类以
public
模式声明,那么基类的成员将按原样被派生类继承。 - private: 在这种情况下,基类的所有成员在派生类中都将成为
private
成员。 - protected: 基类的
public
成员在派生类中将成为protected
成员。
基类的 private
成员在派生类中始终是 private
的。
要了解更多信息,请访问我们的 C++ public、private、protected 继承教程。
继承中的成员函数重写
假设基类和派生类具有相同名称和参数的成员函数。
如果我们创建派生类的对象并尝试访问该成员函数,则会调用派生类中的成员函数,而不是基类中的成员函数。
派生类中的成员函数会覆盖基类中的成员函数。
了解更多关于 C++ 函数重写的信息。