构造函数方法

1. 默认构造函数

没有参数的构造函数。

class Example {
public:
    Example() {}
};

2. 带参数的构造函数

class Example {
public:
    int value;

    Example(int v) : value(v) {}
};

3. 拷贝构造函数

用于通过另一个同类型的对象来创建新对象。

它用于实现深拷贝,特别是当类包含指针成员。

class Example {
public:
    int* value;

    Example(int v) {
        value = new int(v);
    }

    // 拷贝构造函数
    Example(Example& other) {
        value = new int(*(other.value));
    }
};

4. 移动构造函数

用于通过转移资源来创建新对象,避免不必要的拷贝。

这里利用了右值引用。

class Example {
public:
    int* value;

    Example(int v) {
        value = new int(v);
    }

    // 移动构造函数
    Example(Example&& other) noexcept {
        value = other.value;
        other.value = nullptr;
            //nullptr在C++11里表示空指针
    }
};

提一下noexcept关键字,

  noexcept告诉编译器,函数中不会发生异常。
  如果在运行时,该函数向外抛出了异常,

(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常)
  程序会直接终止。

5. 委托构造函数(C++11 引入)

一个构造函数可以调用同一个类中的另一个构造函数。

class Example {
public:
    int value1;
    int value2;

    Example(int v1) : value1(v1), value2(0) {}

    Example(int v1, int v2) : Example(v1) {
        value2 = v2;
    }
};

6. 默认成员初始化器(C++11 引入)

可以在类定义中为成员变量提供默认值。

这些默认值会被所有构造函数使用,除非在构造函数中显式初始化。

class Example {
public:
    int value1 = 5;
    int value2 = 10;

    Example() {}

    Example(int v1) : value1(v1) {
        // value2 仍然使用默认值 10
    }
};

7. 构造函数初始化列表

用于在构造函数的初始化列表中初始化成员变量。

对于常量成员、引用成员和没有默认构造函数的成员,必须使用这种方法。

class Example {
public:
    const int value;
    int& ref;

    Example(int v, int& r) : value(v), ref(r) {}
};

8. 禁用构造函数(C++11 引入)

可以显式地删除构造函数,防止使用特定的构造函数。

class Example {
public:
    Example() = delete; // 禁用默认构造函数

    Example(int v) {}
};

9. 使用构造函数模板

构造函数也可以是模板,以允许不同类型的参数。

template<typename T>
class Example {
public:
    T value;

    Example(T v) : value(v) {}
};
typename也可以用class代替,两者在此处没有区别。

T 可以是任何类数据类型,关于模板就不在此多做赘述。

10.案例

下面做一个小综合案例,联系一下我的上篇文章 关于构造函数使用this指针的问题

#include <iostream>
#include <cstring>

class MenuItem {
public:
    char name[50];
    double price;

    // 默认构造函数
    MenuItem() : price(0.0) {
        name[0] = '\0';
    }

    // 带参数的构造函数
    MenuItem(const char* name, double price) : price(price) {
        int i = 0;
        while (i < sizeof(this->name) - 1 && name[i] != '\0') {
            this->name[i] = name[i];
            i++;
        }
        this->name[i] = '\0';
    }

    // 拷贝构造函数
    MenuItem(const MenuItem& other) : price(other.price) {
        strncpy(this->name, other.name, sizeof(this->name) - 1);
        this->name[sizeof(this->name) - 1] = '\0';
    }

    // 委托构造函数
    MenuItem(double price) : MenuItem("Unknown", price) {}

    void display() {
        std::cout << "商品: " << name << ", 价格: " << price << std::endl;
    }
};

int main() {
    MenuItem item1;
    MenuItem item2("Pizza", 12.99);
    MenuItem item3(item2);
    MenuItem item4(9.99);

    item1.display();
    item2.display();
    item3.display();
    item4.display();

    return 0;
}

ps:这段代码的strncpy函数如果报错,可以在第一行添加

#define _CRT_SECURE_NO_WARNINGS

禁用该警告。

警告的原因是你的编译器认为strncpy不安全。

你也可以这样写:

#include <iostream>
#include <cstring>

class MenuItem {
public:
    char name[50];
    double price;

    // 默认构造函数
    MenuItem() : price(0.0) {
        name[0] = '\0';
    }

    // 带参数的构造函数
    MenuItem(const char* name, double price) : price(price) {
        strncpy_s(this->name, sizeof(this->name), name, _TRUNCATE);
    }

    // 拷贝构造函数
    MenuItem(const MenuItem& other) : price(other.price) {
        strncpy_s(this->name, sizeof(this->name), other.name, _TRUNCATE);
    }

    // 委托构造函数
    MenuItem(double price) : MenuItem("Unknown", price) {}

    void display() {
        std::cout << "商品: " << name << ", 价格: " << price << std::endl;
    }
};

int main() {
    MenuItem item1;
    MenuItem item2("Pizza", 12.99);
    MenuItem item3(item2);
    MenuItem item4(9.99);

    item1.display();
    item2.display();
    item3.display();
    item4.display();

    return 0;
}

用strncpy_s规避该警告,但要注意的传参个数。

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值