C++构造函数

C++构造函数

构造函数特点

(1)函数名必须与类名相同,且没有返回值,可以有参数
(2)在定义对象时自动被调用且仅被调用一次

		——对象定义语句
		——new操作符

(3)作用

		——定义对象的各个成员变量并赋初值,设置对象初始状态
		——在对象定义之初想实现的任何操作

(4)定义类时没有写构造函数,系统提供一个默认的无参构造函数

		——对基本类型的成员变量进行定义,并初始化为随机数
		——对类类型成员变量进行定义,并调用相应类型的无参构造函数
		如果自己定义构造函数,系统就不提供默认的构造函数

(5)一个类可以有多个构造函数,且构成重载关系

构造函数的分类

无参构造

#include <iostream>
#include <cstring>
using namespace std;

class Human
{
public:
    Human()
    {   
        cout << "Human类的构造函数被调用" << endl;
    }   
    void getinfo()
    {   
        cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
    }   
private:
    int m_age;
    char m_name[256];
};

int main(void)
{
    Human h;
    h.getinfo();
    return 0;
}

运行结果
在这里插入图片描述

带参构造函数与缺省构造函数

#include <iostream>
#include <cstring>
using namespace std;

class Human
{
public:
    /* 若为构造函数的所有参数都提供默认值,那么这个构造函数可以充当无参构造函数*/
    Human(/*Human* this*/int age=0,const char* name="wm")
    {
        cout << "Human类的构造函数被调用" << endl;
        this->m_age=age;
        strcpy(this->m_name,name);
    }
    void getinfo()
    {
        cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
    }
private:
    int m_age;
    char m_name[256];
};

int main(void)
{
#if 0
    //默认构造函数的二义性:当我们使用不带参数列表的方式来创建对象时,例如 Human h();
    //C++ 解释器会将其误解为函数声明,因为它也符合函数声明的语法,而且具有函数声明的模式。
    //这是因为 C++ 编译器在遇到这种情况时,认为这是一个函数声明而不是对象的定义。
    Human h();
#endif
    Human h(22,"tom");
    h.getinfo();
    Human h2;
    h2.getinfo();
    Human h3(22);
    h3.getinfo();
    return 0;
}

运行结果
在这里插入图片描述

拷贝构造函数

1.概念

形如:
	class 类名
	{
		类名 (const 类名& that) {...}
	};

2.作用

用一个已定义的对象,来定义其同类型的副本对象,即对象克隆

3.特点

1.调用时机:(1)用已定义对象作为同类型对象的构造实参(2)以对象的形式向函数传递参数(3)从函数中返回对象.(某些拷贝构造过程会被编译器优化)
2.如果一个类没有定义拷贝构造函数,那么编译器会为其提供一个默认拷贝构造函数
		对基本类型成员变量进行定义,并赋初值(按字节复制)
		对类类型成员变量进行定义,并调用相应类型的拷贝构造函数
3.如果自己定义了拷贝构造函数,编译器将不再提供默认拷贝构造函数,这时所有与成员复制有关的操作,都必须在自定义拷贝构造函数中自己编写代码完成
4.所有编译器定义的构造函数,其访问控制属性均为公有(public)
include <iostream>

using namespace std;

class Human
{
public:
    Human(int age=0,const char* name="wr")//构造函数
    {
        cout << "Human类的缺省构造函数被调用" << endl;
        this->m_age=age;
        this->m_name=name;
    }

    Human(const Human& that)
    {
        cout << "Human类的拷贝构造函数被调用" << endl;
        m_age=that.m_age;
        m_name=that.m_name;
    }
    
    void getinfo()
    {   
        cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
    }
private:
    int m_age;
    string m_name;
};

void foo(Human v) {}

int main(void)
{
    Human h;
    h.getinfo();

    Human h2(23,"Tom");
    h2.getinfo();

    Human h3(h2);//用已定义的对象作为同类型对象的构造实参-->触发拷贝构造函数
    h3.getinfo();
    foo(h3);//以对象的形式向函数传递参数--->触发拷贝构造函数
    Human h4=bar();//从函数中返回对象--->触发拷贝构造函数
    return 0;
}

运行结果
在这里插入图片描述

拷贝赋值函数

1.概念

形如:
	class 类名
	{
		类名 operator= (const 类名& that) {}
	};

2.作用

用一个已定义的对象给同类型的对象赋值,即对象赋值

3.特点

1.如果一个类没有定义拷贝赋值函数,那么编译器会为其提供一个默认拷贝赋值函数
	对基本类型成员变量,值传递(按字节复制)
	对类类型成员变量,调用相应类型的拷贝赋值函数
2.如果自己定义了拷贝赋值函数,编译器将不再提供默认拷贝赋值函数,
  这时所有与成员复制有关的操作,都必须在自定义拷贝赋值函数中自己编写代码完成
include <iostream>
using namespace std;

class Human
{
public:
    Human(int age=0,const char* name="wr")//构造函数
    {
        this->m_age=age;
        this->m_name=name;
    }
    Human& operator=(const Human& that)
    {
        cout << "Human类的拷贝赋值函数被调用" << endl;
        this->m_age=that.m_age;
        this->m_name=that.m_name;
        return *this;
    }
    void getinfo()
    {
        cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
    }
private:
    int m_age;
    string m_name;
};

int main(void)
{
    Human h1(23,"Tom");
    h1.getinfo();

    Human h2;
    cout << "h2被赋值前---";
    h2.getinfo();
    h2=h1;
    cout << "h2被赋值后---";
    h2.getinfo();

    return 0;
}

运行结果:
在这里插入图片描述

初始化表

1.特点

类中的基本类型成员变量,最好在初始化表中显式指明如何初始化,否则初值不确定。
类中的类类型成员变量,也最好在初始化表中显式指明如何初始化,否则将调动相应类型的无参构造函数。

2.必须在初始化表中显式初始化的情况

1.const成员变量必须在定义的时候初始化
2.引用成员变量必须在定义的时候初始化
3.没有默认构造函数的自定义类型成员变量
#include <iostream>

using namespace std;

class T
{
public:
    T(int x,int y)
        //若使用编译器的构造函数,或给构造函数提供默认值,可以不在初始化表中显式初始化
    {
        cout << "T构造函数被执行" << endl;
        m_x=x;
        m_y=y;
    }
    void getinfo()
    {
        cout << "T::m_x=" << m_x << ", T::m_y=" << m_y << endl;
    }
private:
    int m_x;
    int m_y;
};

class Time
{
public:
    Time(int year=0,int month=0,int day=0,const int c=0)
    : m_year(year),m_month(month),m_day(day)
      ,m_c(c),ry(m_year),m_a(20,23)
    {
        cout << "Time构造函数被执行" <<endl;
    }
    void getinfo()
    {
        cout << m_year << ":" << m_month << ":" << m_day << endl;
        cout << m_c << endl;
        cout << ry << endl;
        m_a.getinfo();
    }
private:
    int m_year;
    int m_month;
    int m_day;
    const int m_c;//类的 常量型 成员变量 必须在初始化表中显式初始化
    int& ry;//类的 引用型 成员变量 必须在初始化表中显式初始化
    T m_a;//没有默认构造函数的自定义类型成员只能在初始化表中初始化
};

int main(void)
{
    Time t(2023,12,8,16);
    t.getinfo();
    return 0;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值