C++阶段小结(四)

2014-11-24 07:35:58 · 作者: · 浏览: 3
和析构函数不能够被重写;
2.派生类的构造函数被调用时,会先调用基类中的一个构造函数,因为在派生类的构造函数用了初始化表的方式调用了基类构造函数
3.在派生类对象释放时,先执行派生类析构函数,再执行基类析构函数。
派生类构造函数的形式:
派生类构造函数名(总参数列表):基类构造函数名1(参数列表)……基类构造函数名n(参数列表)
十七、继承的二义性
多基继承的二义性
class A1{
public:
int a
int ;
void m();
}
class A2{
public:
int a;
voidm();
}
class B:public A1,public A2{
}
main(){
B b;
b.2=2;//错
b.m();//错
b.A1::a=2//对
b.A!::m();//对
}
由于一个派生类有多个基类,并且基类中的函数形式一样,这种想叫做由于多基继承产生的二义性,这种情况下在派生类中访问产生二义性的基类中的成员时候需要在成员变量前面指定所在的类名和双冒号(::)。
共同基产生的二义性
如果派生类的基类是一模一样的类,在派生类访问基类的成员变量时候也会出现二义性,那么这种情况叫做共同基产生的二义性。
例如:
class B1:public A{};
class B2:public A{};
class C:public B1,public B2{};
共同基产生的二义性的解决办法——虚基派生
例如:
class B1virtual :public A{};
class B2:virtual public A{};
class C:public B1,public B2{};
这样的话在派生类C中只会出现一个A类,可以直接访问基类的变量不会出现二义性。
派生类对象为基类对象赋值
(1) 派生类对象可以向基类对象赋值。
假如A是B的基类:
A a1;
B b1;
a1=b1;
派生类对象可以为基类对象赋值,这个时候只会把从基类继承过来的成员复制过去,而把派生类自己新增的成员舍弃不用;
(2) 基类声明的指针变量和引用类型变量可以用来指向派生类的对象,但是此时只能通过指针或引用访问从基类中继承下来的成员函数和成员变量
假如A是B的基类:
B b;
A *pa=&b;
A &ra=b;
这个时候指针或引用只能够访问从基类A中继承下来的成员函数和成员变量
十八、组合
1.在A类中以B类的对象作为成员变量的,成为类的组合。
2.在组合时,一般A类的构造函数初始化列表中要初始化B类(会调用B类的一个构造函数),如果没有初始化B类,则调用B类中可以不传参数的构造函数。
例如:
class A{
public:
A();
}
class B{
public:
B(int);
B(int a,int b);
}
class C{
public:
A a;
B b;
C(int x,int y);
}
C::C(int x,inty):b(x){};
//C::C(int x,int y):b(x,y){};
//C::C(int x,int y):a(),b(x){};
//C::C(int x,int y):a(),b(x,y){};
十九、多态性
多态性是面向对象程序设计的一个重要特征。利用多态性可以设计和实现一个易于扩展的系统。多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数。向不同的对象发送同一个消息,不同的对象在接到是会产生不同的行为。
多态性分为动态多态性和静态多态性
函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时系统就能够决定用的是哪个重载函数,因此静态多态性又称为编译时的多态性。静态多态性是通过函数的重载实现的。
动态多态性是在程序运行的过程中才动态地确定操作所针对的对象。它又称为运行时的多态性。动态多态性是通过虚函数实现的。
下面来讨论一下虚函数,在讨论虚函数之前必须要弄清楚两个概念
二十、隐藏和重写
隐藏
1.派生类中的成员函数与基类中的成员函数名字相同时,派生类的成员函数会屏蔽基类中同名的成员函数,这种现象叫做隐藏。
2.派生类中的成员变量与基类中的成员变量同名时,派生类的成员变量屏蔽基类中同名的成员变量
3.通过派生类对象、指针、或引用访问基类中被隐蔽的成员时,要在成员前面加上“基类名::”
例如:
//Base.h
class Base{
public:
int x;
void show();
void show(int x);
}
//Child.h
class Child:public Base{
public;
char x;
int show(string name);
}
int main()
{
Child child;
child.x=’c’;//child
child.Base::x=1234;//Base
child.x=1234;//错,这样访问的是child中的x
child.show(“tcc”);//Child
child.Base::show(23);//Base
child.show();//错 参数不对,访问的是child中的show()
}
重写
重写是隐藏的一种特殊情况,当派生类中的成员函数与基类的的名字相同,参数相同,返回值类型相同或者类型兼容,则称为派生类重写了基类函数。
//Base.h
class Base{
public:
void show();
void show(int x);
}
//Child.h
class Child:public Base{
public;
void show();
}
int main(){
Child child;
child.Base::show(12);//Base
child.show();//Child
}
二十一、虚函数
1.在声明函数时,在最前面加上virtual,则该函数就是虚函数,基类的虚函数被派生类继承后仍是虚函数。
2.派生类中可以重写基类的虚函数。
3.用指针访问或引用虚函数时,被访问的虚函数是指针指向的对象所属类的函数(只看指向的对象所属类)。而指针或引用访问重写的普通函数时,被访问的函数是指针或引用类型所属类的函数(只需要看指针或引用类型是什么类)
4.虚函数可以先行动态关联
例如:
class Base {
public:
void show1();
virtual void show2();
};
class Child :public Base{
public:
void show1();
virtual void show2();
int main() {
Child child;