中国大学MOOC程序设计与算法(三):C++ 面向对象程序设计 第二周 类和类的对象基础 笔记 之 构造函数

第二周 类和类的对象基础
1.类和对象的基本概念(2)
2.构造函数
3.复制构造函数
4.类型转换构造函数和析构函数
5.构造函数析构函数调用时机

2.构造函数 constructor

构造函数是成员函数的一种

  1. 名字与类名相同,可以有参数,不能有返回值(void也不行);
  2. 作用是对对象进行初始化,如给成员变量赋初值,在对象已经占用了存储空间以后,对这个空间进行初始化;
  3. 类是一定有构造函数的,如果定义类时没写构造函数,则编译器生成一个默认的无参数的构造函数,默认构造函数无参数,不做任何操作。

-如果定义了构造函数,则编译器不生成默认的无参数的构造函数
-对象生成时(已任何方式生成,包括动态申请内存时)构造函数自动被调用。对象一旦生成,就再也不能在其上执行构造函数。也就是,一个对象只执行一次。
一个类可以有多个构造函数

为什么需要构造函数:

  1. 构造函数执行必要的初始化工作,有了构造函数,就不必专门再写初始化函数,也不用担心忘记调用初始化函数。
  2. 有时对象没被初始化就使用,会导致程序出错
class Complex {
	private :
		double real, imag;
	public:
		void Set( double r, double i);
}; //编译器自动生成默认构造函数
Complex c1; //默认构造函数被调用
Complex * pc = new Complex; //默认构造函数被调用

注意:如果定义类的时候没有定义构造函数,那么生成一个对象时会自动生成默认构造函数,只需要 “类名 对象名”就可以生成一个对象。但是,如果定义类的时候已经定义了构造函数,那么声明一个对象时,一定要加上构造函数的参数进行初始化,否则编译出错,语句是“类名 对象名(参数1,…)",注意此时这个参数可以是在定义时允许缺省的。

class Complex {
	private :
		double real, imag;
	public:
		Complex( double r, double i = 0);//构造函数,和类同名
};
Complex::Complex( double r, double i) {
	real = r; imag = i;
}
Complex c1; // error, 缺少构造函数的参数
Complex * pc = new Complex; // error, 没有参数
Complex c1(2); // OK,第二个参数可以缺省,特殊情况
Complex c1(2,4), c2(3,5);
Complex * pc = new Complex(3,4);

可以有多个构造函数,参数个数或类型不同,重载关系

class Complex {
	private :
		double real, imag;
	public:
		void Set( double r, double i );
		Complex(double r, double i );//复数
		Complex (double r );//实数
		Complex (Complex c1, Complex c2);//复数加法
};
Complex::Complex(double r, double i)
{
	real = r; imag = i;
}
Complex::Complex(double r)
{
	real = r; imag = 0;
}
Complex::Complex (Complex c1, Complex c2);
{
	real = c1.real+c2.real;
	imag = c1.imag+c2.imag;
}
Complex c1(3) , c2 (1,0), c3(c1,c2);
// c1 = {3, 0}, c2 = {1, 0}, c3 = {4, 0};

构造函数最好是public的,private构造函数不能直接用来初始化对象

例子1:

class CSample{
	private:
	CSample() {
	}
};
int main(){
	CSample Obj; //err. 唯一构造函数是private
	return 0;
}

构造函数在数组中的使用

class CSample {
	int x;
public:
	CSample() {
		cout << "Constructor 1 Called" << endl;
	}
	CSample(int n) {
		x = n;
		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;
}

输出:
Constructor 1 Called
Constructor 1 Called
step1
Constructor 2 Called
Constructor 2 Called
step2
Constructor 2 Called
Constructor 1 Called
step3
Constructor 1 Called
Constructor 1 Called

例子2:

class Test {
	public:
		Test( int n) { } //(1)
		Test( int n, int m) { } //(2)
		Test() { } //(3)
};
Test array1[3] = { 1, Test(1,2) };
// 三个元素分别用(1),(2),(3)初始化
Test array2[3] = { Test(2,3), Test(1,2) , 1};
// 三个元素分别用(2),(2),(1)初始化
Test * pArray[3] = { new Test(4), new Test(1,2) };
//两个元素分别用(1),(2) 初始化,只生成了两个对象,第三个没有对象,因为只是定义了一个指针数组,new的时候先初始化一个对象然后返回指针到数组pArray中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值