#include <iostream.h> class A{ int a; public: A(int x):a(x) { cout<<a; } ~A( ) { cout<<a; } }; class B: A{ int b, c; const int d; A x, y; public:
B(int v): b(v),y(b+2),x(b+1), d(b),A(v) { c=v; cout<<b<<c<<d; cout<<'C'; } ~B( ) { cout<<'D'; } }; void main(void) { B z(1); }
这段代码输出什么?
1 先A(V) 为1
2 A x :2
3 A y:3
4 B(int v): 1 1 1 C
5 ~B() : D
6 A y析构:3
7A x析构:2
8 A(v)析构:1
c++的构造函数遵循一个原则
1 虚基类先
2 基类
3 成员定义顺序(初始化列表)
4 派生类构造函数
同时析构函数与其相反。
父类指针实际指向的对象的类型不同,通过父类指针调用的虚函数的行为就不同,从而产生多态#include <iostream.h> 【例6.7】 class Point{ int x, y; public: int getx( ) { return x; } int gety( ) { return y; } void show( ) { cout<<"Show a point\n"; } Point(int x, int y) { Point::x=x; Point::y=y; } }; class Circle: public Point{ int r; public: int getr( ) { return r; }
void show( ) { cout<<"Show a circle\n"; } Circle(int x, int y, int r):Point(x, y) { Circle::r=r; } }; void main(void) { Circle c(3, 7, 8); Point *p=&c; cout<<"The circle with radius "; cout<<c.getr( ); cout<<" is at ("<<p->getx( ); cout<<", "<<p->gety( )<<")\n"; p->show( ); }
这个函数输出什么?由于没有虚函数,因此即使point类的指针 指向的是circle类,但是我们调用 show函数的时候,使用的亦然是,point类的函数,因为编译器之前就将其认为是point类型
不会出现动态的查找情况。
p 编译程序只能根据类型定义静态地检查语义。由于父类指针可以直接指向子类对象,而到底是指向父类对象还是子类对象 只能在运行时确定 ,故编译时只能把父类指针指向的对象都当作父类对象。因此,在访问这些对象的数据成员或函数成员时, 不能超越父类对 象为相应成员规定的访问权限 。
如果基类和派生类没有构成父子关系,则普通函数定义的基类指针不能直接指向派生类对象,而必须通过强制类型转换才能指向派生类对象。
成员函数的重载、覆盖与隐藏
成员函数的重载、覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚
概念,否则错误将防不胜防。
8.2.1 重载与覆盖
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c++构造函数工作原理
最新推荐文章于 2025-03-22 17:27:41 发布