【C++】构造函数、拷贝构造函数、析构函数、内联函数

在这里插入图片描述

上期回顾: 【C++】类和对象
个人主页:C_GUIQU
归属专栏:C++

在这里插入图片描述

正文

1. 构造函数

  • 概念和作用
    • 构造函数用于在创建对象时对对象进行初始化操作。它确保对象在被使用之前处于一个合理的初始状态。
  • 特点
    • 无返回值:构造函数不需要返回任何值,它的任务是初始化对象。
    • 函数名与类名相同:这是构造函数的一个重要标识,编译器通过这个规则来识别构造函数。
    • 必须存在于public中(通常情况):这样才能在类的外部创建对象时调用构造函数。如果构造函数是private的,那么只能在类的内部创建对象,这在一些特殊的设计模式中会用到,但一般情况下我们希望在类的外部能够创建对象,所以构造函数放在public区域。
    • 可以重载:可以定义多个构造函数,只要它们的参数列表不同。这样可以根据不同的初始化需求提供多种方式来创建对象。
    • 不用于初始化static数据成员:因为static数据成员是属于类的,而不是属于某个具体的对象,它在类加载时就会被初始化,不需要通过构造函数来初始化。
  • 默认构造函数(合成的构造函数)
    • 自动生成条件:如果在类中没有给出构造函数,编译器会自动生成一个默认的构造函数。这个默认构造函数是无参数的,并且函数体为空。
    • 消失条件:当在类中手动给出构造函数时,默认的构造函数就会消失。
    • 作用:如果类成员变量有初始值,用这些初始值初始化成员变量;如果类成员变量没有初始值,则默认初始化该成员变量。例如:
class Student { 
public: 
    int age = 18; 
    long id = 217060; 
    std::string name; 
}; 

int main() 
{ 
    // 执行默认构造函数,age、id、name分别被初始化为18、217060、空字符串
    Student stu; 
    return 0; 
}
  • default构造函数(C++11标准)
    • 设计目的:当我们在类中已经手动给出了构造函数,但仍然需要一个默认构造函数时,可以使用=default来定义。
    • 语法=default既可以和声明一起出现在类的内部,也可以作为定义出现在类的外部。如果在类的内部,则默认构造函数是内联的;如果它在类的外部,则该成员默认情况下不是内联的。例如:
class Student { 
public: 
    Student()=default; 
    Student(int age, int id) { 
        this->age = age; 
        this->id = id; 
    } 
public: 
    int age = 18; 
    long id = 217060; 
    std::string name; 
}; 

int main() 
{ 
    Student stu; // 相当于执行了“Student()=default”构造函数,也相当于执行了类的默认构造函数
    return 0; 
}

2. 拷贝构造函数

  • 概念和作用
    • 拷贝构造函数使用一个已经存在的对象去构造(初始化)另一个对象。它在很多情况下会被隐式地调用,比如当我们用一个对象去初始化另一个对象时。
  • 特点
    • 参数加上const&:参数通常为const引用类型(const&)。const是为了防止函数内部修改被拷贝对象的值,&是为了避免无限循环拷贝(如果不是引用类型,在拷贝过程中可能会再次调用拷贝构造函数,导致无限循环)。
  • 分类
    • 浅拷贝
      • 适用情况:当成员变量无动态内存(指针等)变量时,在拷贝构造函数内对成员变量只做简单的赋值,不做内存申请。例如:
class Cperson 
{ 
private: 
    int a; 
public: 
    Cperson(Cperson const& other);//拷贝构造
}; 
Cperson::Cperson(Cperson const& other) 
{ 
    this->a = other.a; 
}

【深拷贝】
适用情况:当成员变量有动态内存(指针等)变量时,在拷贝构造函数内对成员变量先进行内存申请,然后进行内容拷贝。例如:

class Cperson 
{ 
private: 
    int age; 
    char* name; 
public: 
    Cperson(Cperson const& other); 
}; 
Cperson::Cperson(Cperson const& other) 
{ 
    this->age = other->age; 
    if (other.name)//深拷贝
    { 
        int len = strlen(other.name); 
        this->name = new char[len + 1]; 
        strcpy(this->name, other.name); 
    } 
    else 
        this->name = NULL; 
} 
int main() 
{ 
    Cperson person1; 
    Cperson person2(person1);//隐式调用拷贝构造
    Cperson person2 = person1;//显示调用拷贝构造
}
  • 默认拷贝构造函数(合成拷贝构造函数)
    • 规则:如果没有主动给出拷贝构造函数,编译器会自动添加一个拷贝构造函数(做的是浅拷贝)。当主动给出拷贝构造函数后,默认的拷贝构造函数消失。如果类中有动态内存变量出现,必须重写拷贝构造函数,且使用深拷贝;如果没有动态内存变量出现,可以不重写拷贝构造函数,使用默认的即可。

3. 析构函数

  • 概念和作用
    • 析构函数用于对对象进行善后处理,比如释放对象所占用的资源,如指针所指向的内存等。
  • 特点
    • 无返回值:和构造函数一样,析构函数不需要返回任何值。
    • 函数名:~类名:这是析构函数的命名规则,通过在类名前面加上~来标识。
    • 必须存在于public中(通常情况):这样系统才能在对象生命周期结束时自动调用析构函数。
    • 只有一个,不能重载:每个类只能有一个析构函数,因为它的作用是明确的,就是在对象销毁时进行资源清理。
    • 不可以主动调用(通常情况):析构函数是由系统自动执行的,当对象被释放时,系统会自动调用析构函数。不过在一些特殊情况下,比如使用placement new时,可能需要手动调用析构函数,但这是比较复杂的情况。
    • 不用于销毁static数据成员:因为static数据成员是属于类的,它的生命周期和类的生命周期相同,不需要在对象销毁时进行处理。
    • 按成员初始化顺序逆序销毁:与构造函数初始化数据成员的顺序相反,析构函数在执行时,会按照成员初始化顺序的逆序销毁对象的成员。
  • 默认析构函数(合成析构函数)
    • 自动生成条件:如果没有在类中给出析构函数,编译器自动生成一个默认的析构函数。这个默认析构函数是无参数的,并且函数体为空。
    • 消失条件:当手动给出析构函数时,默认的析构函数就会消失。当类中有动态内存的变量时,不能使用默认析构函数,必须手动设计析构函数。例如:
class Cat 
{ 
private: 
    char* name; 
public: 
    ~Cat(); 
}; 
Cat::~Cat() 
{ 
    if(name)//先判断成员是否为空
    { 
        delete[] name; 
        name = nullptr; 
    } 
}

4. 内联函数

  • 概念和作用
    • 内联函数是一种以空间换时间的优化手段。它的作用是在编译阶段将函数体直接嵌入到调用该函数的地方,避免了函数调用的开销(如压栈、弹栈等操作),从而提高程序的执行效率。
  • 与构造函数、析构函数、拷贝构造函数的关系
    • 在构造函数、析构函数和拷贝构造函数中,如果使用=default且在类内定义时,这些函数会被隐式地声明为内联函数。例如,当我们定义一个类的默认构造函数为=default且在类内时:
class MyClass {
public:
    MyClass() = default; // 这个默认构造函数是内联的
};

同样,如果析构函数或拷贝构造函数在类内使用=default,它们也会是内联函数。这种内联的特性在某些情况下可以提高程序的性能,但也会增加代码的体积,需要根据具体情况权衡使用。

结语
感谢您的阅读!期待您的一键三连!欢迎指正!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Guiat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值