继承的意义
继承的本质:a.代码的复用 b. 类和类之间的关系: 组合:a part of… …一部分的关系 继承:a kind of… …一种的关系
我们想让B有A的成员变量  这样写非常麻烦的! 我们可以这样做:  利用继承的方式来复用A中的成员变量
class A
{
public:
int ma;
protected:
int mb;
private:
int mc;
};
class B :public A
{
public:
int md;
protected:
int me;
private:
int mf;
};
B从A继承而来,A派生了B 继承了之后,发生了什么情况? 对于A来说,没有什么影响,用A定义一个对象a,还是12个字节。  我们来看B ,B定义了一个对象b,B是派生类,有2部分,第一部分是从基类继承而来的:ma,mb,mc,第二部分是派生类还有自己的ma,mb,mc  对象b的大小是24个字节。 如果我们现在在派生类中再写一个ma,大小就是28字节了。  现在派生类自己有一个ma,从基类继承而来的也有一个ma,这个名字编译器会不会报错? 不会的。因为作用域不同。派生类从基类继承而来的成员相当于还附带了基类的作用域Base::,下面那个ma是派生类自己的成员,在自己的作用域下。
 基类继承而来的ma是基类作用域下的,自己的ma是派生类作用域下的,作用域不同,派生类和基类的成员名字是可以一样的,不会产生冲突的。  学生是人的一种,这2个类就要设计成继承的关系了,学生从人继承。
派生类从基类继承而来的成员,派生类都可以访问吗? 访问限定是什么?  B类有一个func函数,在这个func函数,对于从A继承来的ma,mb,mc,可不可以访问,访问限定是什么?
在main函数中,只能访问对象的公有成员。  mc占派生类对象的内存,但是在派生对象里,mc是无法访问的。
基类到派生类的成员的访问限定是不可能打印派生类的继承方式的 权限是public>protected>private   实际上,我们可以还有多个继承关系:
 C把B的ma,mb,mc,md,me,mf都继承而来了。 在C里面, 继承而来的成员变量的访问限定是什么,主要是看它的直接基类B里面的访问限定是什么? ma在B中是私有的。  总结: 1.外部只能访问对象public的成员,protected和private的成员无法直接访问 2.在继承结构中,派生类从基类可以继承过来private的成员,但是派生类却无法直接访问 3.protected和private的区别?在基类中定义的成员,想被派生类访问,但是不想被外部访问,那么在基类中,把相关成员定义成protected保护的;如果派生类和外部都不打算访问,那么在基类中,就把相关成员定义成private私有的。
默认的继承方式是什么? 
要看派生类是用class定义的,还是struct定义的 class定义派生类,默认继承方式就是private私有的 struct定义派生类,默认继承方式就是public公有的
派生类的构造过程

  我们来运行上面的代码 编译器报错   这里还是会去找基类的构造函数去构造从基类继承而来的成员 不允许派生类自己去初始化从基类继承而来的成员 怎么办呢?
派生类从继承可以继承来所有的成员(变量和方法),除过构造函数和析构函数 也可以认为是有继承构造函数和析构函数而来,因为在派生类中调用了基类的构造函数
派生类怎么初始化从基类继承来的成员变量呢? 解答:通过调用基类相应的构造函数来初始化
class Base
{
public:
Base(int data) :ma(data) { cout << "Base()" << endl; }
~Base() { cout << "~Base()" << endl; }
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int data)
:Base(data), mb(data)
{
cout << "Derive()" << endl;
}
~Derive()
{
cout << "~Derive()" << endl;
}
private:
int mb;
};
int main()
{
Derive d(20);
return 0;
}
派生类的构造函数和析构函数,负责初始化和清理派生类部分
派生类从基类继承来的成员,的初始化和清理由谁负责呢? 解答:是由基类的构造和析构函数来负责
派生类对象构造和析构的过程是: 1.派生类调用基类的构造函数,初始化从基类继承来的成员 2.调用派生类自己的构造函数,初始化派生类自己特有的成员 …派生类对象的作用域到期了 3.调用派生类的析构函数,释放派生类成员可能占用的外部资源(堆内存,文件) 4.调用基类的析构函数,释放派生类内存中,从基类继承来的成员可能占用的外部资源(堆内存,文件) 
|