标签:
4 派生类的声明
派生类的列表不能出如今派生类的列表中,如:
class B : public A; //error
正确的声明应是:
Class B;
Class A;
5 继承修饰符
C++中的继承方式有三种。public。protected,private继承(简称3p)。
无论是何种继承方式,基类中的private成员
都不能被派生的用户代码和成员定义代码訪问。接下来详细说说三种继承方式:
<1>private继承,基类的全部成员在派生类中都是private成员,可是基类的private成员依然不能被訪问
<2>protected继承,基类的public,protected成员变成子类的protected成员,基类的private成员依然不能被訪问
<3>public继承,基类的public变成派生类的public。protected变成派生类的protected。基类的private不能被訪问
6 protected 修饰符
当protected修饰类成员的时候,类成员能够被类自身成员定义所使用。可是不能被用户代码使用,这点类似private
其次,protected修饰的成员能够被子类訪问到。这点类似public,可是不用于private。
7 不能被继承的成员
构造函数,复制控制成员(复制构造函数,赋值操作符,析构函数)这是不能被继承的函数
8 派生类的构造函数
派生类构造函数一般格式:
DeriveClass(xxx):baseClass(xxx),x1(x),x2(x)....
<1> 派生类的构造函数除了要初始化自己新定义的成员外,还要初始化基类的成员。顺序是先调用基类的构造函数初始化基类的成员。然后再初始化自己的新成员(顺序是声明的顺序)
<2> 假设没有自定义构造函数。编译器会合成一个默认的构造函数,先调用基类的默认构造函数,然后就再去初始化其它新的成员。
<3> 这里须要注意的是:假设基类没有默认构造函数。那么编译器就不能合成默认构造函数,假设这个时候再不去定义派生类的默认构造函数,那样就会出错。诸如--“error C2512: “Derive”: 没有合适的默认构造函数可用。”
<4> 假设不在派生类构造函数的初始化列表中指定基类的构造函数,则会调用基类的默认构造函数
<5> 派生类构造函数的默认实參派生类能够将构造函数的全部參数都设置为默认參数,能够使用0-n个默认參数
9 派生类中的复制控制
复制控制包含复制构造函数,赋值操作符。析构函数
<1>未定义复制构造函数。编译器会自己合成一个复制构造函数,它会调用基类的复制构造函数
<2>自己定义复制构造函数,一般要调用基类的复制构造函数,否则会出意外
<3>未定义赋值操作符。编译会自己主动合成一个赋值操作符,它会调用基类的复制操作符
<4>自己定义赋值操作符要提防自身赋值。一般都是这么做
Derive& Derived::operator =(Derived& rh) { if(this != &rh) { Base::operator=(rh); //do whatever needed to clean up the old value //assign the members from the derived } }
每一个类无论基类还是派生类,都仅仅负责清除自己的成员。
以上的复制控制演示样例代码例如以下所看到的:
#pragma once #include <iostream> using namespace std; class Base { public: Base(){ m = 10;cout<<"Base default constructor"<<endl;} Base(int x):m(x){} Base(Base& rh){cout<<"the base copy constructor"<<endl;}; ~Base(void){cout<<"Base destructor"<<endl;} Base& operator = (Base& base){ this->m = base.m;cout<<"the base operator ="<<endl;return *this;} private: int m; }; class Derive : public Base { public: ~Derive(void){cout<<"Derived destructor"<<endl;} private: int mx; }; void main() { Derive X; cout<<"this is the separtor-----------------"<<endl; Derive Y = X; Y = X; }
依据之前的原则,找到名字同样的就不再往基类找了,所以以下的程序是错误的。
class A { public: void fun(){}; } class B : public A { public: void fun(int){}; private int x; } B b; b.fun(11); //OK b.func(); //error
//Base.h #pragma once #include <iostream> using namespace std; class Base { public: Base(void){ n = 100; }; ~Base(void){}; size_t size()const{return n;} protected: //private: size_t n; int fn(int x){return x;}; int fn(){return 11;} };
//Derived.h #pragma once #include "base.h" class Derived : private Base { public: Derived(void){}; ~Derived(void){}; using Base::size; using Base::fn; };
//main.cpp #include "Base.h" #include "Derived.h" #include <iostream> using namespace std; void main() { Derived XX; Base YY; cout<<XX.size()<<endl; cout<<XX.fn()<<endl; cout<<XX.fn(2)<<endl; system("pause"); }
真可可谓一次声明,多个使用。
12 friend 跟继承的关系
友元跟继承没有关系。基类的派生类不能被基类的派生类訪问。
友元类的派生类对基类没有訪问权限。
13 引用转换,转换对象
引用转换:派生类对象转换为基类类型的引用
转换对象:用派生类对象转换为基类的对象。这个时候形參是固定的。编译和执行时候的对象都是基类类型对象。派生类的基类部分被拷贝到形參中。
引用转换:派生类对象转换为基类的引用。可是假设赋值的话也是把派生类的基类部分赋值给基类对象。这和指针的切片效应一个道理。
14 基类和派生类的转换
派生类转对象赋给基类也是有条件才干行的,这个条件就是派生类是通过public来继承的。这种话不论是在成员代码还是在用户代码中。都能实现
Derived d; Base b = d;
假设是通过protected继承的,那么仅仅能在成员定义中使用这种代码。
15 默认的继承标准
类和结构在默认继承指引相反。
<1>当类继承,假设没有预选赛,那么默认为private继承。如果没有预选赛时的结构,它是默认public继承。
<2>此外strut从开始到内部的第一限定词之间定义的默认public修改。但class缺省值是private修改。
标签:
原文地址:http://www.cnblogs.com/bhlsheji/p/5039802.html