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

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:44   811   0

构造函数:

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

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP