初学C++——郑莉老师的课 第四章 析构函数类的组合大纲及用例

xiaoxiao2021-02-28  38

析构函数——完成对象被删除前的清理工作。编译器会提供默认的析构函数,其函数体为空。

析构函数没有参数,没有返回类型,不能重载。

类的组合概念

类的成员是另一个类的对象,可以在已有的抽象的基础上实现更复杂的抽象。

——组合类的构造函数怎么设计呢?

   组合类有没有权利去访问部件对象内部的私有成员?没有!只有本类的成员函数可以访问,类外不能访问,而且,部件类的设计开发者可能不是一个人。

原则:不仅要负责对本类的基本类型成员初始化,还要对对象成员初始化。

声明形式:类名:类名(对象成员所需的形参,本类成员形参):对象1(参数),对象2(参数),...{函数体其他语句}

构造函数的初始化次序:

初始化顺序:按照成员在类体重定义的顺序调用顺序:按照对象成员的定义顺序,先声明者先构造(初始化列表中未出现的成员对象,调用默认构造函数初始化)执行完初始化列表后,再执行构造函数的函数体。

如果作为部件对象的所属类没有定义默认构造函数,那在初始化组合类对象时,是不是必须得给部件类的对象传递参数?是的,如果不传参数,编译器就会报错。

如果写一个类,希望它能被经常被复用,那么要记住,不管写了多少个构造函数,都要写一个不带参数的默认构函数,因为当这个类的对象用在其他类的部件成员时,可能那个组合类根本就不写构造函数,就用默认构造函数。如果组合类不写构造函数,就没办法给部件对象传参数,这个时候就需要部件对象的一定得有默认构造函数。

例子:

#include<iostream> #include<cmath> using namespace std; class Point //Point类定义 { public: //外部接口 Point(int x = 0, int y = 0) :x(x), y(y) {} //构造函数 Point(const Point &m); //Point(const Point &p); int getX() { return x; } int getY() { return y; } private: //私有数据成员 int x, y; }; //成员函数的实现 Point::Point(const Point &p) { x = p.x; y = p.y; cout << "calling the copy constructor" << endl; } //形参为Point类对象的函数 void fun1(Point p) { cout << p.getX() << endl; } //返回值为Point类对象的函数 Point fun2() { Point a; return a; } class Line { public: Line(Point xp1, Point xp2); Line(const Line &l); double getLen() { return len; } private: Point p1, p2;//Point类的对象p1,p2 double len; }; //组合类的构造函数 Line::Line(Point xp1, Point xp2) :p1(xp1), p2(xp2)//两个参数都是Point类的对象,要完成形实结合,才能进入函数里 //先要进入Point类的拷贝构造函数。 //调用了两次Point类的拷贝构造后,开始执行组合类的构造函数 //先初始化列表,p1和p2被初始化的顺序是什么样的呢?不管初始化列表怎么写,初始化的次序取决于 //在类里定义的时候,哪个参数在前面。显然p1在前面定义,所以先初始化p1 //在初始化p1时,又会进入Point类的拷贝构造函数。同理,初始化p2也一样。然后进入函数体。 { cout << "calling the cnstructor of line" << endl; double x = static_cast<double>(p1.getX() - p2.getY()); double y= static_cast<double>(p1.getY() - p2.getX()); len = sqrt(x*x + y*x); } //组合类的拷贝构造函数 Line::Line(const Line &l):p1(l.p1),p2(l.p2) //用l的p1端点初始化新对象p1,端点p2初始化新对象p2,肯定要构造Point类的拷贝构造函数 //会调用两次Point类的拷贝构造函数,然后进入函数体内。 { cout << "calling the copy constructor of Line" << endl; len = l.len; } int main() { Point myp1(1, 1), myp2(4, 5); Line line(myp1, myp2);//建立Line类的对象,形式结合传参数时,是从最后一个对象开始传递的 //即先把myp2的(4,5)传给形参,再传递myp1的值,同样会调用Point类的拷贝构造 //实形结合完后,接着进入Line类的构造函数 Line line2(line);//利用拷贝狗仔函数建立一个新对象 cout << "the length of the line is"; cout << line.getLen() << endl; cout << "the length of the line2 is"; return 0; }

转载请注明原文地址: https://www.6miu.com/read-2620842.html

最新回复(0)