深入解析C++五种构造函数:从默认到移动构造

开发
想象一下,在C++的王国里住着一个构造函数家族。这个家族有四个成员,他们都有各自的特长,一起帮助我们创建对象。

想象一下,在C++的王国里住着一个构造函数家族。这个家族有四个成员,他们都有各自的特长,一起帮助我们创建对象。让我们通过一个披萨店的例子来认识这个有趣的家族吧! 

默认构造函数 - 基础款披萨师傅

在C++的世界里,默认构造函数就像一位只会制作基础款披萨的师傅👨🍳,他总是默默无闻地为你准备好一个9寸的奶酪披萨🧀。当你什么都不说时,他就会自信地拿出他的经典作品,虽然简单,但绝对美味😋。这位师傅虽然不花哨,但在你需要时总能派上用场,像一位可靠的老朋友👯♂️。所以,当你需要一个能吃的披萨时,别忘了这位基础款披萨师傅的存在哦!🍕✨

class Pizza {
public:
    // 默认构造函数
    Pizza() {
        size = 9;  // 9寸披萨
        topping = "cheese";  // 默认奶酪配料
    }
private:
    int size;
    string topping;
};

// 使用默认构造函数
Pizza myPizza;  // 得到一个9寸奶酪披萨

带参构造函数 - 点餐小能手

想象一下,这位带参构造函数就像一位超级贴心的点餐小能手 🤗!当你走进披萨店,不想要普普通通的披萨时,ta就是你的最佳帮手!无论你想要巨无霸尺寸 📏,还是独特口味 🌟,这位点餐小能手都能完美记住你的要求,就像有个小本本 📝 记录着你的每个心愿~

class Pizza {
public:
    // 带参构造函数 - 你说啥就是啥 🎯
    Pizza(int s, string t) : size(s), topping(t) {
        cout << "收到!马上为您制作" << size << "寸的" << topping << "披萨!🍕" << endl;
    }
private:
    int size;      // 披萨尺寸 📏
    string topping; // 独特配料 ✨
};

// 心情不错?来个超大夏威夷吧!🌺
Pizza hawaiianPizza(12, "菠萝火腿");  // 这个搭配好像有点争议呢 🤔

有了这位点餐小能手,你再也不用担心吃到不合口味的披萨啦!想要什么尺寸、什么配料,只要一说,立刻就能帮你安排妥妥的 🎉!就像有个专属订制师,随时待命,为你打造完美披萨体验 ⭐️!

拷贝构造函数 - 复制大师

哎呀,这位复制大师可是披萨店里的"影分身之术"专家呢!🥷 想象一下,当客人说"我要一个跟他一模一样的披萨"时,复制大师就会施展魔法 ✨,把原版披萨的每个细节都完美复刻下来 - 从尺寸到配料,就连芝士的位置都分毫不差!就像照镜子一样,连双胞胎都要自叹不如呢 👯♂️

class Pizza {
public:
    // 复制大师的独门秘技 🎯
    Pizza(const Pizza& other) {
        size = other.size;
        topping = other.topping;
        cout << "哒哒!✨ 复制魔法完成啦!" << endl;
    }
    // ...其他厨艺秘诀
};

// 以下三种情况都会召唤出复制大师:
Pizza originalPizza(12, "pepperoni");     // 原版杰作
Pizza copiedPizza = originalPizza;        // 方式1:使用 = 初始化
Pizza anotherPizza(originalPizza);        // 方式2:直接调用拷贝构造
void makeOrder(Pizza p) { /*...*/ }       // 方式3:函数参数传递
makeOrder(originalPizza);                 // 这里也会触发拷贝构造

有趣的是,当我们使用= 进行初始化时(比如Pizza copiedPizza = originalPizza),这实际上是在调用拷贝构造函数,而不是赋值运算!这是因为我们是在创建新的披萨(对象),而不是把已经做好的披萨换成另一个。这就像是在开新店时,直接按照原店的配方和布局来装修,而不是把原店搬过来。🏪✨

注意:不要把拷贝构造(Pizza a = b)和赋值运算(Pizza a; a = b)搞混了哦!赋值运算是另一位大师 - 赋值运算符(operator=)的专长呢!🔄

不过这位大师也有个小小的困扰...当需要复制的披萨特别多时,一个个复制难免会很耗时耗力。这时候我们的快递小哥就派上用场啦! 🚚

移动构造函数 - 闪电快递侠

嘿!认识一下这位超级快递侠吧!🦸♂️ 他可不是普通的外卖小哥,而是能以光速送披萨的超级英雄!🚀 当厨房做好一份"临时"披萨时,他不会傻傻地复制一份新的(那多浪费时间啊!),而是直接 "嗖~"的一下,闪电般把披萨转移到你手中!💫 就像变魔术一样,披萨从这边消失 ✨,瞬间出现在那边,快到连影子都看不见!🎭

class Pizza {
public:
    // 闪电快递侠的独门绝技 ⚡️
    Pizza(Pizza&& other) noexcept {
        size = other.size;                        // 记住披萨尺寸 📏
        topping = std::move(other.topping);       // 施展转移魔法 ✨
        cout << "披萨瞬间传送成功啦!💫" << endl;
        
        // 原来的披萨位置变空啦(毕竟已经被传送走了)🎈
        other.size = 0;
        other.topping = "";
    }
};

// 来看看快递侠是怎么工作的
Pizza makePizza() {
    return Pizza(14, "supreme");  // 制作一个临时披萨 🍕
}

// 见证奇迹的时刻
Pizza myPizza = makePizza();  // 瞬间传送!比光速还快!⚡️

这位快递小哥特别擅长处理临时订单(临时对象)。当遇到这种情况时,他不会像复制大师那样重新制作一份,而是直接把现成的披萨转移给你。这样不仅速度快,还能节省资源! 🎯

小贴士: 移动构造函数通常会被标记为 noexcept,表示承诺在转移过程中不会抛出异常,这让编译器能够放心地优化代码。就像快递小哥向你保证:放心,包裹一定安全送达! 📦✨

委托构造函数 - 团队协作小能手

想象一下,在这个繁忙的披萨店里,还有一位特别的成员 - 委托构造小能手!他不直接制作披萨,而是善于"委托"其他师傅来完成工作。就像一个超级组织者,他知道每位师傅的特长,总能找到最合适的人选来完成订单!🎯

class Pizza {
public:
    // 主厨的完整配方
    Pizza(int s, string t, bool extraCheese) : 
        size(s), topping(t), hasExtraCheese(extraCheese) {
        cout << "制作完整版披萨!" << endl;
    }
    
    // 委托给主厨,默认加双份芝士
    Pizza(int s, string t) : Pizza(s, t, true) {
        cout << "双倍芝士版本真香!🧀" << endl;
    }
    
    // 懒人套餐:委托制作标准12寸双倍芝士披萨
    Pizza() : Pizza(12, "cheese") {
        cout << "标准版披萨准备完成!" << endl;
    }

private:
    int size;
    string topping;
    bool hasExtraCheese;
};

// 看看怎么使用
Pizza standardPizza;              // 制作标准12寸双倍芝士披萨
Pizza cheesePizza(10, "cheese"); // 10寸双倍芝士披萨
Pizza customPizza(14, "supreme", false); // 14寸至尊披萨,普通芝士

委托构造函数就像是披萨店里的"传话筒",它可以把客人的订单转交给更专业的师傅来完成。这样不仅避免了重复的工作,还能确保每份披萨都符合统一的品质标准。比如当客人只说要一个披萨时,委托构造函数就会默默地帮你选择最受欢迎的标准款式!

小贴士:使用委托构造函数可以减少代码重复,提高代码的可维护性。就像披萨店里的工作流程一样,让专业的人做专业的事!👨🍳✨

总结

这五位构造函数家族成员各有所长:

  • 默认构造函数负责基础款
  • 带参构造函数处理定制需求
  • 拷贝构造函数善于完美复制
  • 移动构造函数专注效率优化
  • 委托构造函数团队协作

了解他们的特长,在合适的场景选择合适的成员,就能让我们的程序更加高效优雅! 🌟

责任编辑:赵宁宁 来源: everystep
相关推荐

2010-02-01 11:01:30

C++静态构造函数

2010-01-25 17:05:37

C++语言

2024-04-28 11:01:27

C++编程语言函数

2010-01-28 10:49:22

C++构造函数

2023-11-28 11:51:01

C++函数

2022-07-26 00:36:06

C#C++函数

2010-01-27 17:16:52

C++构造函数

2024-12-11 08:00:00

移动语义C++

2010-01-22 11:13:16

C++静态

2010-01-27 10:13:22

C++类对象

2010-01-27 16:10:32

C++静态构造函数

2010-01-25 14:00:27

C++类

2014-05-29 10:54:20

C++构造函数

2021-12-10 10:45:36

C++函数Stock

2010-01-25 14:43:00

C++构造函数

2010-02-02 17:39:31

C++构造函数

2024-12-31 00:07:12

2009-08-13 17:30:30

C#构造函数

2010-07-16 16:56:01

Perl构造函数

2010-01-20 18:06:06

C++虚基类
点赞
收藏

51CTO技术栈公众号