C++学习笔记11 构造函数与析构函数

构造函数:

C++中的类可以定义与类名相同的特殊成员函数

这种与类名相同的成员函数叫做构造函数

构造函数在定义的时候可以有参数,但是没有任何返回类型的声明

class Test
{
	private:
		int i;
		int j;
		int k;
	public:
		
		Test() 
		{
			i = j = k =0;
		}
		Test(int v)
		{
			i = j = k = v;
		}
		
		void print()
		{
			printf("i = %d,j = %d, k = %d\n",i,j,k);
		}
		
		void print(int v)
		{
			printf("v = %d\n",v);
		}
};


构造函数的调用:

一般情况下C++编译器会自动调用构造函数

在一些情况下则需要手工调用构造函数

int main(int argc, char** argv) {
	
	Test t1(4); //自动调用构造函数 
	Test t2 = 5;//自动调用构造函数 
	Test t3 = Test(8);//手动调用构造函数
	
	//Test tA[3] ; ERROR
	Test tA[3] = {Test(1),Test(2),Test(3)}; //手动调用构造函数 
	for(int i = 0; i< 3;i++)
	{
		tA[i].print();
	}
	
	t1.print();
	t2.print();
	t3.print();	
	
	
	getchar(); 
	return 0;
}

成员函数的重载:

类的成员函数与普通函数一样可以进行重载,并遵守相同的重载规则。

class Test
{
	private:
		int i;
		int j;
		int k;
	public:
		
		Test() 
		{
			i = j = k =0;
		}
		Test(int v)
		{
			i = j = k = v;
		}
		
		void print()
		{
			printf("i = %d,j = %d, k = %d\n",i,j,k);
		}
		
		void print(int v)
		{
			printf("v = %d\n",v);
		}
};


两个特殊的构造函数:

class Test
{
public:
	/*
	Test()
	{
		printf("Test()\n");
	}
	*/ 
	Test(const Test& obj)
	{
		printf("Tset(const Test& obj)");
	}
	
};

int main(int argc, char** argv) {
	
	Test t1;
	Test t2 = t1;

	getchar(); 
	return 0;
}

两个特殊的构造函数分别是:

无参构造函数:当类中没有定义任何一种构造函数的时候,编译器默认提供一个无参构造函数,并且它的函数体为空,不做任何处理,只是使得编译通过

拷贝构造函数:当类中没有定义拷贝构造函数的时候,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制。

#include <iostream>
#include <stdio.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

/*
注意:
1:当类中没有定义任何一个构造函数,C++编译器会为我们提供无参构造函数和拷贝构造函数
2:当类中定义了任意的非拷贝构造函数时,C++编译器不会为我们提供无参构造函数 
3:当类中定义了一个拷贝构造函数时,编译器也不会提供无参构造函数 
*/
class Test
{
	
private:
	
	int i;
	int j;
	int k;
	 
public:
	void print()
	{
		printf("i = %d, j = %d , k = %d\n", i,j,k);
	}
	
};

int main(int argc, char** argv) {
	
	Test t1;//调用无参构造函数,函数体为空,不做任何事情,就是为了可以编译通过 
	Test t2 = t1; 
	//这里输出的值一样,说明系统提供的拷贝构造函数做了一些事情,就是成员变量的复制,这里就是把
	//t1的成员变量的值都赋值给t2的成员变量,所以两者输出的一样。 
	t1.print();
	t2.print();
	

	getchar(); 
	return 0;
}

上面代码,最重要的注意是: t1.print()与t2.print()输出的值一样,因为 t2 = t1 这里调用了编译器自己提供的默认拷贝构造函数

它做的事情就是简单的成员变量的赋值,即:t2.i = t1.i;t2.j = t1.j; t2.k = t1.k;所以两者输出的值是一样的。

 


写一个数组类:

#include <iostream>
#include <stdio.h>
#include "Array.h"

int main(int argc, char** argv) {
	
	
	Array a1(10);
	
	for(int i = 0 ;i < a1.length(); i++)
	{
		 a1.setData(i,i);
	}
	for(int i = 0; i< a1.length(); i++)
	{
		printf("Element i = %d\n", a1.getData(i));
	}
	printf("**********************************\n");
	
	Array a2 = a1;
	for(int i = 0; i< a2.length(); i++)
	{
		printf("Element i = %d\n", a2.getData(i));
	}
	
	a1.destory();
	
	a2.destory();
	//如果这里才用系统提供的默认的拷贝构造函数,它只是进行单纯的复制工作,所以a1与a2中的mSpace指向的是
	//同一个空间,当执行a1.destory之后,这片空间已经释放,执行a2.destory就会出错 
	
	
	getchar(); 
	return 0;
}


 

#ifndef _ARRAY_H_ 
#define _ARRAY_H_

#endif
class Array
{
	private:
		int mLength;
		int *mSpace;
		
	public:
		Array(int length);
		Array(const Array& obj);
		int length();
		void setData(int index, int value);
		int getData(int index);
		void destory();
};


 

#include "Array.h"

Array::Array(int length)
{
	if(length < 0)
	length = 0;
	mLength = length;
	mSpace = new int[mLength];
}

Array::Array(const Array& obj)
{
	mLength = obj.mLength;
	mSpace = new int[mLength]; //自己申请一个新的空间出来,而系统提供的就是指向同一个空间。 
	for(int i = 0; i < mLength; i++)
	{
		mSpace[i] = obj.mSpace[i];
	}
}
int Array::length()
{
	return mLength;
} 

void Array::setData(int index , int value)
{
	mSpace[index] = value;
}

int Array::getData(int index)
{
	return mSpace[index];
}

void Array::destory()
{
	mLength = -1;
	delete[] mSpace;
}


总结:

构造函数是C++中用于初始化对象状态的特殊函数

构造函数在对象创建的时候自动被调用

构造函数和普通成员函数都遵循重载规则

拷贝构造函数是对象正确初始化的重要保证

 

注意:
1:当类中没有定义任何一个构造函数,C++编译器会为我们提供无参构造函数和拷贝构造函数
2:当类中定义了任意的非拷贝构造函数时,C++编译器不会为我们提供无参构造函数,但是会提供默认的拷贝构造函数

class Test
{
public:
	
	Test()
	{
		printf("Test()\n");
	}
	/*
	Test(const Test& obj)
	{
		printf("Tset(const Test& obj)");
	}
	*/
	
};

int main(int argc, char** argv) {
	
	Test t1;
	Test t2 = t1;

	getchar(); 
	return 0;
}

上面代码只提供了一个非拷贝构造函数,但是Test t2 = t1 仍然编译通过,说明编译器为我们提供了默认的拷贝构造函数。

3:当类中定义了一个拷贝构造函数时,编译器也不会提供无参构造函数(总之只要有一个我们自己添加的构造函数,编译器就不会再提供无参构造函数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值