C++之继承与派生(1)
http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/08/2130817.html
继承是面向对象程序设计中的重要特性,是软件复用的一种形式。其实继承和派生就是同一种概念的不同说法罢了,通常我们说子类继承父类,父类派生出子类。说实话,学习和了解了C++的继承与派生后,发现我对面向对象中的继承与派生有了更深刻的理解。在更加深入了解C++关于继承方面的知识之前,我想先讲一下C++中派生与继承的基本概念,它是之后学习派生类的构造与析构,以及多重继承等的基础。
1.派生类的声明
声明一个派生类的一般格式:
class 派生类名:[继承方式] 基类名
{
派生类新增的数据成员和成员函数
};
对于上述的格式主要想说一下继承方式的作用,它主要是规定如何访问从基类继承的成员。它可以有关键字private、protected和public来分别表示私有继承、保护继承和公有继承。如果不显示继承方式关键字,系统默认为私有继承。继承方式指定类派生类成员以及类外对象对于从基类继承来的成员的访问权限。
2.对于不同的继承方式,基类成员在派生类中的访问属性也是不同的,以下表,列出了基类成员在派生类中的访问属性(我想以一张表格的方式来说明,既显而易见,又简单易懂):
3.最后说一下,派生类对基类成员的访问规则,无非访问方式就两种:内部访问和对象访问。同样的3中继承方式下,派生类对基类成员的访问也分为3类。对于3种访问规则,我将用实例和小结一一对应:
(1).私有继承的访问规则:
示例:
#include "stdafx.h"
#include <iostream>
class A
{
private:
int a1;
protected:
int a2;
public:
int a3;
A(int a1);
void showA();
};
A::A(int a1)
{
this->a1=a1;
}
void A::showA()
{
std::cout<<"a1="<<this->a1<<std::endl;
}
class B:private A
{
private:
int b;
public:
B(int b,int a1,int a2,int a3);
void showB();
};
B::B(int b,int a1,int a2,int a3):A(a1)
{
this->a2=a2;//内部可以访问
this->a3=a3;//内部可以访问
this->b=b;
}
void B::showB()
{
//std::cout<<"a1="<<this->a1<<std::endl;不可访问
showA();//间接访问
std::cout<<"a2="<<this->a2<<std::endl;
std::cout<<"a3="<<this->a3<<std::endl;
std::cout<<"b="<<this->b<<std::endl;
}
int main()
{
B b(4,1,2,3);
//b.a1=5;//类外不可访问
//b.a3=5;类外不可访问
//b.a2=5;类外不可访问
//b.showA();类外不可访问
b.showB();
return0;
}
结果:
由以上示例可小结:
私有继承那么派生类继承下来的基类中的成员,在派生类中就都成为了私有成员,因此,派生类的对象访问任何基类中的成员(数据成员a1,a2,a3和成员函数showA())都不允许,而派生类内部不可访问基类中的私有成员(a1),可访问保护成员(a2)和公有成员(数据成员a3,成员函数showA());
(2).保护继承的访问规则:
对上述示例代码中的private继承换为protected
#include <iostream> 3 4 class A 5 { 6 private: 7 int a1; 8 protected: 9 int a2;10 public:11 int a3;12 A(int a1);13 void showA();14 };15 16 A::A(int a1)17 {18 this->a1=a1;19 }20 void A::showA()21 {22 std::cout<<"a1="<<this->a1<<std::endl;23 }24 25 26 class B:protected A //保护继承27 {28 private:29 int b;30 public:31 B(int b,int a1,int a2,int a3);32 void showB();33 };34 35 B::B(int b,int a1,int a2,int a3):A(a1)36 {37 this->a2=a2;//内部可以访问38 this->a3=a3;//内部可以访问39 this->b=b;40 }41 42 void B::showB()43 {44 //std::cout<<"a1="<<this->a1<<std::endl;不可访问45 showA();//间接访问46 std::cout<<"a2="<<this->a2<<std::endl;47 std::cout<<"a3="<<this->a3<<std::endl;48 std::cout<<"b="<<this->b<<std::endl;49 }50 51 52 int main()53 {54 B b(4,1,2,3);55 //b.a1=5;//类外不可访问56 //b.a3=5;类外不可访问57 //b.a2=5;类外不可访问58 //b.showA();类外不可访问59 b.showB();60 61 return0;62 }
由以上示例可小结(运行结果和上一示例相同):
保护继承那么派生类继承下来的基类中的成员,除了私有的基类成员不变外,在派生类中就都成为了保护成员,因此,派生类内部不可访问基类中的私有成员(a1),可访问保护成员(a2)和公有成员(数据成员a3,成员函数showA());而派生类的对象访问任何基类中的成员(数据成员a1,a2,a3和成员函数showA())都不允许,a1是私有成员,不能访问,但a2,a3和showA()被继承下来在派生类中是保护成员,它们不能访问是因为protected保护类型的成员可以被本类的成员函数访问,也可以被继承被类的的派生类成员函数访问,但类以外的任何访问都不允许,即它为半隐蔽的。
(3).公有继承的访问规则:
示例:
#include <iostream>
class A
{
private:
int a1;
protected:
int a2;
public:
int a3;
A(int a1);
void showA();
};
A::A(int a1)
{
this->a1=a1;
}
void A::showA()
{
std::cout<<"a1="<<this->a1<<std::endl;
}
class B:public A //公有继承
{
private:
int b;
public:
B(int b,int a1,int a2,int a3);
void showB();
};
B::B(int b,int a1,int a2,int a3):A(a1)
{
this->a2=a2;//内部可以访问
this->a3=a3;//内部可以访问
this->b=b;
}
void B::showB()
{
//std::cout<<"a1="<<this->a1<<std::endl;不可访问
//showA();//间接访问
std::cout<<"a2="<<this->a2<<std::endl;
std::cout<<"a3="<<this->a3<<std::endl;
std::cout<<"b="<<this->b<<std::endl;
}
int main()
{
B b(4,1,2,3);
//b.a1=5;//类外不可访问
//b.a2=5;类外不可访问
b.a3=5;
b.showA();
b.showB();
return0;
}
结果:
由以上示例可小结:
公有继承那么派生类继承下来的基类中的成员,除了私有的基类成员和保护的基类成员不变外,在派生类中就都成为了公有成员,因此,派生类内部不可访问基类中的私有成员(a1),可访问保护成员(a2)和公有成员(数据成员a3,成员函数showA());而派生类的对象可以访问基类中数据成员a3和成员函数showA(),但不允许访问私有成员a1和保护成员a2。
4.最后总结一下,其实这节所讲的内容归根到底就是对于继承方式的理解,以及从继承方式所引出的访问属性和规则的相对应的不同区别。因为觉得直接用文字来表达,看起来会比较乱,所以试着参入表格和示例小结来说明。希望这样能达到读者在看这篇随笔时不会觉得思绪很混乱!