C++ 构造函数(第四章)

本文详细介绍了构造函数的基本概念、形式及调用时机等知识点,并通过具体示例解释了默认构造函数、复制构造函数和委托构造函数的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

构造函数基本概念

构造函数的作用

构造函数的形式

构造函数的调用时机

默认构造函数

隐含生成的构造函数

“=default”

例4_1修改版1

例4_1修改版2

委托构造函数

回顾

委托构造函数

复制构造函数

复制构造函数定义

隐含的复制构造函数

“=delete”

复制构造函数被调用的三种情况

例 4-2 Point 类的完整程序

析构函数


构造函数基本概念

构造函数的作用

 在对象被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态。

 例如:

         希望在构造一个Clock类对象时,将初试时间设为0:0:0,就可以通过构造函数来 设置。

构造函数的形式

 函数名与类名相同;

 不能定义返回值类型,也不能有return语句;

 可以有形式参数,也可以没有形式参数;

 可以是内联函数;

 可以重载;

 可以带默认参数值。

构造函数的调用时机

 在对象创建时被自动调用

 例如:

Clock myClock(0,0,0);

默认构造函数

 调用时可以不需要实参的构造函数

         参数表为空的构造函数

         全部参数都有默认值的构造函数

 下面两个都是默认构造函数,如在类中同时出现,将产生编译错误:

Clock(); 
Clock(int newH=0,int newM=0,int newS=0); 

隐含生成的构造函数

 如果程序中未定义构造函数,编译器将在需要时自动生成一个默认构造函数

         参数列表为空,不为数据成员设置初始值;

         如果类内定义了成员的初始值,则使用内类定义的初始值;

         如果没有定义类内的初始值,则以默认方式初始化;

         基本类型的数据默认初始化的值是不确定的。

“=default”

 如果程序中未定义构造函数,默认情况下编译器就不再隐含生成默认构造函数。如果 此时依然希望编译器隐含生成默认构造函数,可以使用“=default”。

 例如

class Clock {
public:
	Clock() = default; //指示编译器提供默认构造函数
	Clock(int newH, int newM, int newS); //构造函数
private:
	int hour, minute, second;
}

构造函数例题(1)

例4_1修改版1

//类定义

class Clock {

public:

     Clock(int newH,int newM,int newS);//构造函数

     void setTime(int newH, int newM, int newS);

     void showTime();

private:

     int hour, minute, second;

};


//构造函数的实现:

Clock::Clock(int newH,int newM,int newS): hour(newH),minute(newM),  second(newS) {

     }

//其它函数实现同例4_1


int main() {

  Clock c(0,0,0); //自动调用构造函数

  c.showTime();

     return 0;

}

例4_1修改版2

class Clock {

public:

       Clock(int newH, int newM, int newS); //构造函数

       Clock(); //默认构造函数

       void setTime(int newH, int newM, int newS);

       void showTime();

private:

       int hour, minute, second;

};

Clock::Clock(): hour(0),minute(0),second(0) { }//默认构造函数

//其它函数实现同前


int main() {

    Clock c1(0, 0, 0);       //调用有参数的构造函数

    Clock c2;         //调用无参数的构造函数

   ……

}

委托构造函数

类中往往有多个构造函数,只是参数表和初始化列表不同,其初始化算法都是相同的, 这时,为了避免代码重复,可以使用委托构造函数。

回顾

Clock类的两个构造函数:
Clock(int newH, int newM, int newS) : hour(newH), minute(newM),
second(newS) { //构造函数
}
Clock::Clock() : hour(0), minute(0), second(0) { }//默认构造函数

委托构造函数

 委托构造函数使用类的其他构造函数执行初始化过程

 例如:

Clock(int newH, int newM, int newS): hour(newH),minute(newM), 
second(newS){
}
Clock(): Clock(0, 0, 0) { }

复制构造函数

复制构造函数定义

复制构造函数是一种特殊的构造函数,其形参为本类的对象引用。作用是用一个已 存在的对象去初始化同类型的新对象。

class 类名 {
public :
 类名(形参);//构造函数
 类名(const 类名 &对象名);//复制构造函数
 // ...
};
类名::类( const 类名 &对象名)//复制构造函数的实现
{ 函数体 }

隐含的复制构造函数

 如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个隐含的复制构 造函数。  这个构造函数执行的功能是:用作为初始值的对象的每个数据成员的值,初始化将要 建立的对象的对应数据成员。

“=delete”

 如果不希望对象被复制构造

         C++98做法:将复制构造函数声明为private,并且不提供函数的实现。

         C++11做法:用“=delete”指示编译器不生成默认复制构造函数。

 例:

class Point { //Point 类的定义
public:
Point(int xx=0, int yy=0) { x = xx; y = yy; } //构造函数,内联
Point(const Point& p) =delete; //指示编译器不生成默认复制构造函数
private:
int x, y; //私有数据
};

复制构造函数被调用的三种情况

 定义一个对象时,以本类另一个对象作为初始值,发生复制构造

 如果函数的形参是类的对象,调用函数时,将使用实参对象初始化形参对象,发生复 制构造;  如果函数的返回值是类的对象,函数执行完成返回主调函数时,将使用return语句中 的对象初始化一个临时无名对象,传递给主调函数,此时发生复制构造。

          这种情况也可以通过移动构造避免不必要的复制(第6章介绍)

例 4-2 Point 类的完整程序

#include <iostream>
using namespace std;

class Point { //Point 类的定义
public:
	Point(int xx = 0, int yy = 0) { x = xx; y = yy; } //构造函数,内联
	Point(const Point& p); //复制构造函数
	void setX(int xx) { x = xx; }
	void setY(int yy) { y = yy; }
	int getX() const { return x; } //常函数(第5章)
	int getY() const { return y; } //常函数(第5章)
private:
	int x, y; //私有数据
};
//复制构造函数的实现
Point::Point(const Point& p) {
	x = p.x;
	y = p.y;
	cout << "Calling the copy constructor " << endl;
}
//形参为Point类对象
void fun1(Point p)
{
	cout << p.getX() << endl;
}
//返回值为Point类对象
Point fun2()
{
	Point a(1, 2);
	return a;
}
int main() {
	Point a(4, 5);
	Point b(a); //用a初始化b。
	cout << b.getX() << endl;
	fun1(b); //对象b作为fun1的实参
	b = fun2(); //函数的返回值是类对象
	cout << b.getX() << endl;
	return 0;
}

析构函数

  • 完成对象被删除前的一些清理工作。

  • 在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间。

  • 如果程序中未声明析构函数,编译器将自动产生一个默认的析构函数,其函数体为空。

  • 构造函数和析构函数举例

  • #include <iostream>
    
    using namespace std;
    class Point {     
    public:
      Point(int xx,int yy);
      ~Point();
      //...其他函数原型
    private:
      int x, y;
    };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值