C++语言程序设计之类和对象进阶(2)

1 编程练习一

        通过编程练习一,读者能够对析构函数、静态成员、常量成员函数、封闭类及其复制构造函数、const成员和引用成员有比较深入的理解。

1.1 析构函数(1)

        析构函数在对象消亡时自动调用,在面向对象编程中起着回收内存空间的作用。

1.1.1 设计代码

#include 
using namespace std;
class CDemo
{
public:
	~CDemo() //析构函数
	{
		cout << "Destructor called" << endl;
	}
};
int main()
{
	CDemo array[2];//构造函数调用2次
	CDemo* pTest = new CDemo;//构造函数调用
	delete pTest;  //析构函数调用
	cout << "----------" << endl;
	pTest = new CDemo[2];//构造函数调用2次
	delete [] pTest;     //析构函数调用2次
	cout << "Main ends." << endl;
	return 0;
}

1.1.2 执行结果

C++语言程序设计之类和对象进阶(2)_第1张图片 图1 析构函数(1)代码执行结果

1.2 析构函数(2)

        函数的参数对象,以及函数的返回值对象,在消亡时会引发析构函数的调用。

1.2.1 设计代码

#include 
using namespace std;
class CDemo
{
public:
	~CDemo() { cout << "destructor" << endl; }
};
void Func(CDemo obj)
{
	cout << "func" << endl;
}
CDemo d1;
CDemo Test()
{
	cout << "test" << endl;
	return d1;
}
int main()
{
	CDemo d2;
	Func(d2);
	Test();
	cout << "after test" << endl;
	return 0;
}

1.2.2 执行结果

C++语言程序设计之类和对象进阶(2)_第2张图片 图2 析构函数(2)代码执行结果

1.3 构造函数、析构函数和变量的生存期

        类的对象在生成时构造函数被调用,对象在消亡时析构函数被调用。

1.3.1 设计代码

#include 
using namespace std;
class Demo
{
	int id;
public:
	Demo(int i)
	{
		id = i;
		cout << "id=" << id << " constructed" << endl;
	}
	~Demo()
	{
		cout << "id=" << id << " destructed" << endl;
	}
};
Demo d1(1);
void Func()
{
	static Demo d2(2);
	Demo d3(3);
	cout << "func" << endl;
}
int main()
{
	Demo d4(4);
	d4 = 6;
	cout << "main" << endl;
	{
		Demo d5(5);
	}
	Func();
	cout << "main ends" << endl;
	return 0;
}

1.3.2 执行结果

C++语言程序设计之类和对象进阶(2)_第3张图片 图3 构造函数、析构函数和变量的生存期代码执行结果

1.4 静态成员

        类的静态成员有两种,分别是静态成员变量和静态成员函数。静态成员变量的本质是全局变量,静态成员函数的本质是全局函数。

1.4.1 设计代码

#include 
using namespace std;
class CRectangle
{
private:
	int w, h;
	static int totalArea;   //矩形总面积
	static int totalNumber; //矩形总数
public:
	CRectangle(int w_, int h_);
	~CRectangle();
	static void PrintTotal();
	CRectangle(CRectangle& r) {
		totalNumber++;
		totalArea += r.w * r.h;
		w = r.w; h = r.h;
	}
};
CRectangle::CRectangle(int w_, int h_)
{
	w = w_; h = h_;
	totalNumber++;     //有对象生成则增加总数
	totalArea += w * h;//有对象生成则增加总面积
}
CRectangle::~CRectangle()
{
	totalNumber--;     //有对象消亡减少总数
	totalArea -= w * h;//有对象消亡则减少总面积
}
void CRectangle::PrintTotal()
{
	cout << totalNumber << ", " << totalArea << endl;
}
int CRectangle::totalNumber = 0;
int CRectangle::totalArea = 0;
//必须在定义类的文件中对静态成员变量进行一次声明
//或初始化,否则编译能通过,链接不能通过
int main()
{
	CRectangle r1(3, 3), r2(2, 2);
	CRectangle::PrintTotal();
	r1.PrintTotal();
	return 0;
}

1.4.2 执行结果

图4 静态成员代码执行结果

1.5 常量成员函数(1)

        常量成员函数使用const关键字。

1.5.1 设计代码

#include 
using namespace std;
class Sample {
public:
	void GetValue() const;
};
void Sample::GetValue() const
{
	cout << "const" << endl;
}
int main()
{
	const Sample o;
	o.GetValue();//常量对象上可以执行常量成员函数
	return 0;
}

1.5.2 执行结果

图5 常量成员函数(1)代码执行结果

1.6 常量成员函数(2)

        常量成员对象上可以调用常量成员函数。

1.6.1 设计代码

#include 
using namespace std;
class CTest {
private:
	int n;
public:
	CTest() { n = 1; }
	int GetValue() const { return n; }
	int GetValue() { return 2 * n; }
};
int main() {
	const CTest objTest1;
	CTest objTest2;
	cout << objTest1.GetValue() << ", " << objTest2.GetValue();
	cout << endl;
	return 0;
}

1.6.2 执行结果

图6 常量成员函数(2)代码执行结果

1.7 封闭类

        一个类的成员变量如果是另一个类的对象,那么包含成员对象的类叫做封闭类。

1.7.1 设计代码

#include 
using namespace std;
class CTyre    //轮胎类
{
private:
	int radius;//半径
	int width; //宽度
public:
	CTyre(int r, int w) :radius(r), width(w)
	{
		cout << "CTyre constructor" << endl;
	}
	~CTyre()
	{
		cout << "Tyre destructor" << endl;
	}
};
class CEngine  //引擎类
{
public:
	CEngine()
	{
		cout << "CEngine constructor" << endl;
	}
	~CEngine()
	{
		cout << "CEngine destructor" << endl;
	}
};
class CCar     //汽车类
{
private:
	int price; //价格
	CTyre tyre;
	CEngine engine;
public:
	CCar(int p, int tr, int tw);
	~CCar()
	{
		cout << "CCar destructor" << endl;
	}
};
CCar::CCar(int p, int tr, int tw) :price(p), tyre(tr, tw)
{
	cout << "CCar constructor" << endl;
};
int main()
{
	CCar car(20000, 17, 225);
	return 0;
}

1.7.2 执行结果

C++语言程序设计之类和对象进阶(2)_第4张图片 图7 封闭类代码执行结果

1.8 封闭类的复制构造函数

        对于封闭类的复制构造函数,如果封闭类的对象是用默认复制构造函数初始化的,那么成员对象也要用复制构造函数初始化。

1.8.1 设计代码

#include 
using namespace std;
class A
{
public:
	A() { cout << "default" << endl; }
	A(A& a) { cout << "copy" << endl; }
};
class B
{
	A a;
};
int main()
{
	B b1, b2(b1);
	return 0;
}

1.8.2 执行结果

图8 封闭类的复制构造函数代码执行结果

1.9 const成员和引用成员

        常量型成员变量和引用型成员变量,必须在构造函数的初始化列表中进行初始化。

1.9.1 设计代码

#include 
using namespace std;
int f;
class CDemo {
private:
	const int num;//常量型成员变量
	int& ref;     //引用型成员变量
	int value;
public:
	CDemo(int n) :num(n), ref(f), value(4)
	{
	}
	void PrintCDemo()
	{
		cout << num << "," << ref << "," << value << endl;
	}
};
int main() {
	cout << sizeof(CDemo) << endl;
	CDemo c(5);
	f = 3;
	c.PrintCDemo();
	return 0;
}

1.9.2 执行结果

图9 const成员和引用成员代码执行结果

2 编程练习二:返回什么才好呢

        在非静态成员函数内部,可以直接使用this关键字,this代表指向函数所作用对象的指针。

2.1 设计代码

#include 
using namespace std;
class A {
public:
	int val;

	A(int
		// 在此处补充你的代码
		m = 123):val(m){
	}
	A& GetObj(){
		return *this;
	}
};
int main()
{
	int m, n;
	A a;
	cout << a.val << endl;
	while (cin >> m >> n) {
		a.GetObj() = m;
		cout << a.val << endl;
		a.GetObj() = A(n);
		cout << a.val << endl;
	}
	return 0;
}

2.2 执行结果

C++语言程序设计之类和对象进阶(2)_第5张图片 图10 返回什么才好呢代码执行结果

3 解题心得

  • C++类和对象中,析构函数起到释放消亡对象的内存空间的作用,避免编程人员忘记释放空间。
  • 静态成员变量的本质是全局变量,静态成员函数的本质是全局函数。
  • 封闭类中有成员变量是另一个类的对象。
  • 只有this指针才能够找到类的对象的地址。

你可能感兴趣的:(C++程序设计,c++,开发语言,算法)