在本文中,您将学习在C ++中使用公共继承,受保护继承和私有继承。您将通过示例学习在何处以及如何使用它。您可以从具有不同访问指定的基类声明一个派生类,即公共继承,受保护继承或私有继承。
#includeusing namespace std; class base { .... ... .... }; class derived : access_specifier base { .... ... .... };
注意:可以使用public,protected或private关键字代替上面代码中使用的access_specifier(访问说明符)术语。
派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。
我们可以根据访问权限总结出不同的访问类型,如下所示:
访问 | public | protected | private |
---|---|---|---|
同一个类 | yes | yes | yes |
派生类 | yes | yes | no |
外部的类 | yes | no | no |
一个派生类继承了所有的基类方法,但下列情况除外:
基类的构造函数、析构函数和拷贝构造函数。
基类的重载运算符。
基类的友元函数。
当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种类型。继承类型是通过上面讲解的访问修饰符 access-specifier 来指定的。
我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:
公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
(1)基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。
(2)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
(3)通过派生类的对象访问从基类继承的成员,只能访问public成员。
示例:
#include
using namespace std;
class CFather
{
public:
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
class CSon: public CFather
{
void test()
{
m_testA = 1; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
m_testB = 1; // 编译正确 :public 继承后,在内部可以访问protected成员
m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
}
};
int main()
{
CSon _test;
_test.m_testA = 2; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
_test.m_testB = 2; // 编译错误 :public 继承后,在外部无法访问protected成员
_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
system("pause");
return 0;
}
保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
(1)基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员`不可直接``访问。
(2)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
(3)通过派生类的对象不能直接访问从基类继承的任何成员。
示例:
#include
using namespace std;
class CFather
{
public:
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
class CSon: protected CFather
{
void test()
{
m_testA = 1; // 编译正确 :protected 继承后,在内部可以访问public成员
m_testB = 1; // 编译正确 :protected 继承后,在内部可以访问protected成员
m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
}
};
int main()
{
CSon _test;
_test.m_testA = 2; // 编译错误 :protected 继承后,在外部无法访问public成员
_test.m_testB = 2; // 编译错误 :protected 继承后,在外部无法访问protected成员
_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
system("pause");
return 0;
}
此时,可以这么理解为 派生类 通过 protected
继承 基类 之后 ,基类 中的 public
变成了protected
,其他保持原样。
class CFather
{
protected:// proteced 继承之后public变成了 proteced
int m_testA{0};
protected:
int m_testB{0};
private:
int m_testC{0};
};
私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
(1)基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。
(2)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
(3)通过派生类的对象不能直接访问从基类继承的任何成员。
示例:
#include
using namespace std;
class CFather // 基类
{
public:
int m_testA{ 0 }; // 相当于int m_testA = 0;
protected:
int m_testB{ 0 };
private:
int m_testC{ 0 };
};
class CSon : private CFather // 私有继承(private)
{
void test()
{
m_testA = 1; // 编译正确 :private 继承后,在内部可以访问基类public成员
m_testB = 1; // 编译正确 :private 继承后,在内部可以访问基类protected成员
m_testC = 1; // 编译错误 :无论哪种继承,都无法访问基类private成员
}
};
int main()
{
CSon _test;
_test.m_testA = 2; // 编译错误 :private 继承后,在外部无法访问基类public成员
_test.m_testB = 2; // 编译错误 :private 继承后,在外部无法访问基类protected成员
_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问基类private成员
return 0;
}
此时,可以这么理解为 派生类 通过 private
继承 基类 之后 ,基类 中的 public
与protected
变成了private
,其他保持原样。
class CFather
{
private:// private 继承之后public变成了 private
int m_testA{0};
private:// private 继承之后protected变成了 private
int m_testB{0};
private:
int m_testC{0};
};
三者区别
public继承方式
基类中所有 public 成员在派生类中为 public 属性;
基类中所有 protected 成员在派生类中为 protected 属性;
基类中所有 private 成员在派生类中不能使用。
protected继承方式
基类中的所有 public 成员在派生类中为 protected 属性;
基类中的所有 protected 成员在派生类中为 protected 属性;
基类中的所有 private 成员在派生类中不能使用。
private继承方式
基类中的所有 public 成员在派生类中均为 private 属性;
基类中的所有 protected 成员在派生类中均为 private 属性;
基类中的所有 private 成员在派生类中不能使用。
多继承即一个子类可以有多个父类,它继承了多个父类的特性。
C++ 类可以从多个类继承成员,语法如下:
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,… { <派生类类体> };
其中,访问修饰符继承方式是 public、protected 或 private 其中的一个,用来修饰每个基类,各个基类之间用逗号分隔,如上所示。现在让我们一起看看下面的示例:
#include
// 基类 Shape
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHight(int h) {
height = h;
}
protected:
int width;
int height;
};
// 基类PaintCost
class PaintCost {
public:
int getCost(int area) {
return area * 70;
}
};
// 派生类
class Rectangle :public Shape, public PaintCost {
public:
int getArea() {
return (width * height);
}
};
int main() {
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHight(7);
area = Rect.getArea();
// 输出对象的面积
std::cout << "总面积:" << Rect.getArea() << std:: endl;
// 输出总花费
std::cout << "总花费:¥" << Rect.getCost(area) << std::endl;
return 0;
}
输出结果:
部分参考自:
C++的三种继承方式详解_c++继承的三种方式_NueXini的博客-CSDN博客