C++语言程序设计之类和对象进阶(1)构造函数

1 编程练习一

        通过这一部分的编程练习,读者能够深入理解构造函数。

1.1 有多个构造函数的Complex类

        一个类可以有多个构造函数。

1.1.1 设计代码

#include 
using namespace std;
class Complex {
private:
	double real, imag;
public:
	Complex(double r);
	Complex(double r, double i);
	Complex(Complex c1, Complex c2);
	void PrintComplex() {
		cout << real << "," << imag << endl;
	}
};
Complex::Complex(double r)               //构造函数1
{
	real = r; imag = 0;
}
Complex::Complex(double r, double i)     //构造函数2
{
	real = r; imag = i;
}
Complex::Complex(Complex c1, Complex c2) //构造函数3
{
	real = c1.real + c2.real;
	imag = c1.imag + c2.imag;
}
int main()
{
	Complex c1(3), c2(1, 2), c3(c1, c2), c4 = 7;
	c1.PrintComplex();
	c2.PrintComplex();
	c3.PrintComplex();
	c4.PrintComplex();
	return 0;
}

1.1.2 执行结果

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

1.2 构造函数和数组(1)

        数组中构造函数的调用情况如下。

1.2.1 设计代码

#include 
using namespace std;
class CSample
{
public:
	CSample() {      //构造函数1
		cout << "Constructor 1 Called" << endl;
	}
	CSample(int n) { //构造函数2
		cout << "Constructor 2 Called" << endl;
	}
};
int main()
{
	CSample array1[2];
	cout << "step1" << endl;
	CSample array2[2] = { 4, 5 };
	cout << "step2" << endl;
	CSample array3[2] = { 3 };
	cout << "step3" << endl;
	CSample* array4 = new CSample[2];
	delete[] array4;
	return 0;
}

1.2.2 执行结果

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

1.3 构造函数和数组(2)

        数组初始化列表中需要显式包含对构造函数的调用的情况,是构造函数有多个形参。

1.3.1 设计代码

#include 
using namespace std;
class CTest
{
public:
	CTest(int n)        //构造函数(1)
	{
		cout << "Constructor 1 Called" << endl;
	}
	CTest(int n, int m) //构造函数(2)
	{
		cout << "Constructor 2 Called" << endl;
	}
	CTest()             //构造函数(3)
	{
		cout << "Constructor 3 Called" << endl;
	}
};
int main() {
	//三个元素分别用构造函数(1)、(2)、(3)初始化
	CTest array1[3] = { 1,CTest(1,2) };
	cout << "step1" << endl;
	//三个元素分别用构造函数(2)、(2)、(1)初始化
	CTest array2[3] = { CTest(2,3),CTest(1,2),1 };
	cout << "step2" << endl;
	//两个元素指向的对象分别用构造函数(1)、(2)初始化
	CTest* pArray[3] = { new CTest(4),new CTest(1,2) };
	return 0;
}

1.3.2 执行结果

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

1.4 复制构造函数

        此处说明复制构造函数的使用。

1.4.1 设计代码

#include 
using namespace std;
class Complex
{
public:
	double real, imag;
	Complex(double r, double i)
	{
		real = r; imag = i;
	}
};
int main()
{
	Complex c1(1, 2);
	Complex c2(c1);//用复制构造函数初始化c2
	cout << c2.real << ", " << c2.imag << endl;
	return 0;
}

1.4.2 执行结果

图4 复制构造函数代码执行结果

1.5 非默认复制构造函数

        非默认复制构造函数,是用户写出的复制构造函数。

1.5.1 设计代码

#include 
using namespace std;
class Complex {
public:
	double real, imag;
	Complex(double r, double i)
	{
		real = r; imag = i;
	}
	Complex(const Complex& c)
	{
		real = c.real; imag = c.imag;
		cout << "Copy Constructor called" << endl;
	}
};
int main()
{
	Complex c1(1, 2);
	Complex c2(c1);//调用复制构造函数
	cout << c2.real << ", " << c2.imag << endl;
	return 0;
}

1.5.2 执行结果

图5 非默认复制构造函数代码执行结果

1.6 复制构造函数用于函数形参

        函数的形参是类的对象时,这个类的复制构造函数被调用。

1.6.1 设计代码

#include 
using namespace std;
class A
{
public:
	A() {};
	A(A& a)
	{
		cout << "Copy constructor called" << endl;
	}
};
void Func(A a)
{
}
int main()
{
	A a;
	Func(a);
	return 0;
}

1.6.2 执行结果

图6 复制构造函数用于函数形参代码执行结果

1.7 复制构造函数用于函数返回对象

        函数返回类的对象时,这个类的复制构造函数被调用。

1.7.1 设计代码

#include 
using namespace std;
class A
{
public:
	int v;
	A(int n) { v = n; };
	A(const A& a)
	{
		v = a.v;
		cout << "Copy constructor called" << endl;
	}
};
A a(4);
A Func()
{
//	A a(4);
	return a;
}
int main()
{
	auto i = 8;
	cout << Func().v << endl;
	return 0;
}

1.7.2 执行结果

图7 复制构造函数用于函数返回对象代码执行结果

1.8 类型转换构造函数

        除复制构造函数外,只有一个参数的构造函数,可以称为类型转换构造函数。

1.8.1 设计代码

#include 
using namespace std;
class Complex
{
public:
	double real, imag;
	Complex(int i) //类型转换构造函数
	{
		cout << "IntConstructor called" << endl;
		real = i; imag = 0;
	}
	Complex(double r, double i)
	{
		real = r; imag = i;
	}
};
int main()
{
	Complex c1(7, 8);
	Complex c2 = 12;
	c1 = 9; //9被自动转换成一个临时Complex对象
	cout << c1.real << ", " << c1.imag << endl;
	return 0;
}

1.8.2 执行结果

图8 类型转换构造函数代码执行结果

2 编程练习二:奇怪的类复制

        复制构造函数,可以完成类复制。此处的复制构造函数,是非默认复制构造函数,它完成的功能是在类复制的基础上做了新类的修改。

2.1 设计代码

#include 
using namespace std;
class Sample {
public:
	int v;
	// 在此处补充你的代码
	Sample() { v = 3; }
	Sample(int a)
	{
		v = a;
	}
	Sample(const Sample& c)
	{
		v = c.v + 2;
	}
};
void PrintAndDouble(Sample o)
{
	cout << o.v;
	cout << endl;
}
int main()
{
	Sample a(5);
	Sample b = a;
	PrintAndDouble(b);
	Sample c = 20;
	PrintAndDouble(c);
	Sample d;
	d = a;
	cout << d.v;
	return 0;
}

2.2 执行结果

图9 奇怪的类复制代码执行结果

3 解题心得

  • 构造函数用于完成类中成员变量的初始化操作,以防止程序员忘记初始化类的成员变量。
  • 复制构造函数用于完成类的复制。
  • 非默认复制构造函数完成的功能,可以不是类复制,而是创建一个与之前的类所不同的类。
  • 当用一个类对象去初始化另一个类对象时,当类对象作为函数的参数时,当函数返回类对象时,类的复制构造函数都会被调用。
  • 类型转换构造函数,是指除复制构造函数外,只有一个参数的构造函数。

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