构造函数和析构函数 (C++)

133 阅读3分钟

构造函数和析构函数(C++)

在编程时,持有某些数据成员和成员函数的对象必须在对其进行操作之前被初始化。这通常是由成员函数完成的,它将数据成员初始化为预定义的值。但是,有一种特殊的成员函数,当对象第一次被构造时,会自动初始化它。这个特殊的成员函数被称为构造函数

从实质上讲,构造函数为类的数据成员定义了一个值。构造函数是一个特殊的成员函数,用于在构造类的对象时即时初始化它。

使用和声明一个构造函数

  • 构造函数是一个成员函数,它的名字与类的名字相同。
  • 它的定义与类的任何其他成员函数(包括内部或外部)一样。
  • 由于构造函数只是定义了一个数据成员的值,所以它没有返回类型。
  • 当对象被创建时,它们被自动调用。
  • 它们应该在类的公共部分中声明。
  • 声明语法。考虑到类的名称和构造函数的名称是demo。让ab是两个整数变量。
class demo
	{
		private:
			int a,b;
		public:
			demo()
				{
				a=1;
				b=2;
				}
	};
展示构造函数使用的C++程序

考虑寻找一个圆的面积的程序。类的名称将是demo。两个成员函数将被声明,一个用于输入,一个用于输出。由于构造函数的名称应与类的名称相同,所以构造函数的名称也将是demo。当构造函数demo被声明后,类对象的初始化将自动完成。

#include <iostream>
#include<conio.h>
using namespace std;

class demo
{
  private:
     double radius, pi;
   public:
     void input(double r);
     double output();
     demo();
};

demo::demo(void)    //constructor definition outside the class
{
   pi=3.142;
}
void demo::input(double r)
{
  radius=r;
}
double demo::output(void)
{
  return (pi*radius*radius);
}

int main()
{
  demo d1;

  d1.input(5.5);
  cout<<"Area of the circle is : "<<d1.output()<<"sq.units"<<"\n";
  return 0;
  getch();
}

上述程序的输出是。

Area of the circle is : 95.0455sq.units

上述程序也可以通过在类内定义构造函数来编写。在类内定义构造函数的代码段如下。

class demo
{
   private:
      double radius, pi;
    public:
      void input(double r);
      double output();
      demo()        //constructor definition inside the class
            {
                pi=3.142;
            }
};

构造函数的类型

默认构造函数

一个没有任何参数的构造器被称为默认构造器,或 "零参数构造器"。在默认构造函数中,类中的每个对象都被初始化为同一组值。不可能用不同的初始值来初始化不同的对象。这是默认构造函数的缺点之一。

语法。考虑一个名字为world的类。这个类的默认构造函数是。

world :: world()   //default constructor without any arguments

**注意:**任何带参数的构造函数都不是默认构造函数。

参数化构造函数

*为了避免默认构造函数接受参数的不可行性,我们使用参数化构造函数,它是一个可以接受一个或多个参数的构造函数。*它的工作方式与默认构造函数相同,但不同的是它可以容纳参数。一旦对象被创建,它们也会被自动调用。参数化构造函数的另一个属性是,它们可以被重载。

**语法。**考虑一个名字为world的类。这个类的参数化构造函数应该是。

world :: world(int a, int b)     //parameterized constructor with arguments

复制构造函数

*复制构造函数是一种参数化构造函数,其中一个对象的属性可以被复制到另一个对象。*它被用来用已经存在的对象的值来初始化一个对象。当一个现有的对象作为参数被传递时,拷贝构造函数被调用。

**注意:**拷贝构造函数不能被显式调用。

语法。考虑一个名字为world的类。这个类的复制构造函数是。

world :: world(world &ptr)        //copy constructor

其中,ptr 是指向类对象的指针。

调用(调用)构造函数

显式调用

显式调用是一种调用构造函数的方法,其中通过使用赋值运算符(=)、构造函数名称和参数列表来完成对象的声明。

语法。

constructor_name object_name=constructor_name(argument list);
用来演示显式调用的C++程序

考虑一下计算圆的面积的程序。类和构造函数的名称将是演示。构造函数将通过接受一个参数而被参数化。在这里,d1作为对象,将数值5.5明确地转移到构造函数中。

#include <iostream>
#include<conio.h>
using namespace std;

class demo
{
	private:
		double radius, area;
	public:
		demo(double r)
	{
	radius=r;
	}
	void output()
	{
	area=3.142*radius*radius;
	cout<<"The area of the circle is: "<<area<<"sq.units"<<"\n";
	}
};

int main()
{
	demo d1=demo(5.5);
	d1.output();
	return 0;
	getch();
}

上述程序的输出将是。

The area of the circle is: 95.0455sq.units

隐式调用

隐式调用是一种调用构造函数的方法,在这种方法中,先进行对象的声明,然后是一个参数列表。

语法。

constructor_name object_name(argument list);
演示隐式调用的C++程序

考虑一下计算圆的面积的程序。类和构造函数的名称将是演示。构造函数将通过接受一个参数而被参数化。在这里,d1作为对象,隐含地将值5.5转移到构造函数中。

#include <iostream>
#include<conio.h>
using namespace std;

class demo
{
	private:
		double radius, area;
	public:
		demo(double r)
	{
	radius=r;
	}
	void output()
	{
	area=3.142*radius*radius;
	cout<<"The area of the circle is: "<<area<<"sq.units"<<"\n";
	}
};

int main()
{
	demo d1(5.5);
	d1.output();
	return 0;
	getch();
}

上述程序的输出将是。

The area of the circle is: 95.0455sq.units

**注意:**对于不同的值,不同的对象必须在主函数中被初始化。

构造函数重载

我们知道构造函数是用来初始化类的数据成员的。它们也可以用于初始化数据成员的特定输入值。但这不能通过使用默认构造函数来实现,因为它们不接受任何参数。因此,要做到这一点,必须对默认构造函数进行重载,也就是说,应该用额外的参数对它们进行初始化。对象的初始化必须牢记参数的数量。然后编译器根据参数列表决定调用哪个构造函数。

看看这个简单的片段。考虑类名和构造函数名是demo

class demo
	{
		private:
			... data members of the class...
		public:
			demo()                 //default constructor
			{ }
			demo(argument list)   //parameterized constructor
			{
			...operations on the variables...
			}
	};

考虑d1d2是对象。当对象d1被创建时,默认的构造函数被调用,而当对象d2被创建并带有一些参数时,参数化构造函数被调用。

int main()
{
	demo d1(), d2(argument list)
	return 0;
	getch();
}

解构器

正如在介绍中提到的,构造函数是一个特殊的成员函数,每当一个对象被创建时,它就会被立即调用。同样地,析构函数是一种类型的函数,当一个对象被销毁时,它被立即调用。通过这样做,它将初始化到一个变量的值和它的内存去掉。它们没有返回值。它们不接受任何参数,因此它们不能被重载。它的名字与类相同(就像构造函数一样),但前面有蒂尔德标记(符号为~)。请看下面的代码片段,看看析构器是如何工作的。

class demo
	{
		private:
			int a,b,c;
		public:
			demo();         //constructor
			~demo();       //destructor
	};