C++ 语言特性10 - 委托构造函数

news2024/10/4 22:15:23

1:什么是委托构造函数?

        在C++中,委托构造函数(Delegating Constructor)是一种特殊的构造函数,它在构造函数的初始化列表中调用同一个类中的另一个构造函数,从而实现代码的复用。这种特性在C++11中引入。

class MyClass {
public:
    // 委托构造函数
    MyClass(int x, int y) : MyClass(x) {
        // 委托给另一个构造函数
    }
    
    // 被委托的构造函数
    MyClass(int x) {
        // 初始化代码
    }
};

2. 委托构造函数在什么场景中使用?

  • 代码复用: 当多个构造函数需要执行相同的初始化步骤时,可以使用委托构造函数来避免代码重复。

#include <iostream>
#include <string>

class Person {
public:
    Person() : Person("Unknown", 0) {
        std::cout << "Default constructor called\n";
    }
    
    Person(std::string name) : Person(name, 0) {
        std::cout << "Name constructor called\n";
    }
    
    Person(std::string name, int age) : name(name), age(age) {
        std::cout << "Full constructor called for " << name << std::endl;
    }

private:
    std::string name;
    int age;
};

int main() {
    Person p1;
    Person p2("Alice");
    Person p3("Bob", 30);
    return 0;
}
  • 链式委托: 一个构造函数可以委托给另一个构造函数,而后者又可以委托给下一个,形成一个委托链。

class Matrix {
public:
    Matrix() : Matrix(0, nullptr) {
        std::cout << "Default constructor called\n";
    }
    
    Matrix(size_t rows, size_t cols) : Matrix(rows, cols, new double*[rows]) {
        std::cout << "Size constructor called\n";
    }
    
    Matrix(size_t rows, size_t cols, double** data) : rows(rows), cols(cols), data(data) {
        std::cout << "Data constructor called\n";
    }

private:
    size_t rows;
    size_t cols;
    double** data;
};

int main() {
    Matrix mat;
    return 0;
}
  • 继承和覆盖: 在继承的类中,可以利用委托构造函数调用基类的构造函数,以确保正确的初始化。

class Base {
public:
    Base(int x) {
        std::cout << "Base constructor with int called\n";
    }
};

class Derived : public Base {
public:
    // 委托给基类的构造函数
    Derived(double x) : Base(static_cast<int>(x)) {
        std::cout << "Derived constructor with double called\n";
    }
};

int main() {
    Derived d(3.14);
    return 0;
}

3. 注意事项:

  • 委托目标的选择: 确保委托的目标构造函数是有效的,并且能够正确初始化对象。

#include <iostream>
#include <string>
#include <vector>

class Data {
public:
    // 正确的委托目标选择
    Data(const std::string& str) : Data(str.begin(), str.end()) {}
    
    // 正确的初始化列表
    Data(const char* begin, const char* end) {
        // 做一些初始化工作
        for (; begin != end; ++begin) {
            values.push_back(*begin);
        }
        std::cout << "Data initialized with " << values.size() << " elements." << std::endl;
    }

private:
    std::vector<char> values;
};

int main() {
    Data d("Hello");
    return 0;
}
  • 构造函数的递归调用: 避免构造函数之间的无限递归调用。

class RecursiveConstructor {
public:
    // 错误:递归调用自身
    RecursiveConstructor() : RecursiveConstructor(42) {}
    
    RecursiveConstructor(int) {
        std::cout << "Constructor called" << std::endl;
    }
};

int main() {
    // RecursiveConstructor rc; // 这将导致无限递归调用
    return 0;
}
  • 资源管理: 在委托构造函数中,确保资源被正确管理和释放。

#include <iostream>

class Resource {
public:
    // 委托构造函数正确地管理资源
    Resource(int id) : Resource(id, new int(id * 10)) {
        std::cout << "Resource ID: " << *data << std::endl;
    }
    
    // 被委托的构造函数
    Resource(int id, int* data) : id(id), data(data) {}
    
    ~Resource() {
        delete data;
    }

private:
    int id;
    int* data;
};

int main() {
    Resource res(1);
    return 0;
}

//在这个例子中,委托构造函数确保了资源(动态分配的整数)被正确地分配和初始化。
  • 异常安全: 委托构造函数需要考虑异常安全性,确保在抛出异常时对象处于一致的状态。

#include <iostream>
#include <string>

class ExceptionSafe {
public:
    // 委托构造函数
    ExceptionSafe(const std::string& str) : ExceptionSafe(str.begin(), str.end()) {
        // 做一些可能会抛出异常的操作
        if (str.empty()) {
            throw std::invalid_argument("String is empty");
        }
    }
    
    // 被委托的构造函数
    ExceptionSafe(const char* begin, const char* end) {
        // 做一些初始化工作
        try {
            for (; begin != end; ++begin) {
                values.push_back(*begin);
            }
        } catch (...) {
            // 异常发生时进行清理工作
            std::cout << "Exception caught during initialization." << std::endl;
            throw;
        }
        std::cout << "Data initialized with " << values.size() << " elements." << std::endl;
    }

private:
    std::vector<char> values;
};

int main() {
    try {
        ExceptionSafe es("Hello");
        ExceptionSafe esEmpty("");
    } catch (const std::exception& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2188805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink 03 | 数据流基本操作

Flink数据流结构 DataStream 转换 通常我们需要分析的业务数据可能存在如下问题&#xff1a; 数据中包含一些我们不需要的数据 数据格式不方面分析 因此我们需要对原始数据流进行加工&#xff0c;比如过滤、转换等操作才可以进行数据分析。 “ Flink DataStream 转换主要作…

C++ -引用-详解

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【C】 欢迎点赞&#x1f44d;收藏⭐关注❤️ C -引用-详解 1.引用基础1.1是什么1.2特点 2.引用的意义3.引用的应用场景3.1作为参数3.2作为返回值传值返回引用返回 4.权限问题5.与指针的区别6.总结 1.引用基础 1.1是什么 …

SpringBoot整合异步任务执行

同步任务&#xff1a; 同步任务是在单线程中按顺序执行&#xff0c;每次只有一个任务在执行&#xff0c;不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务&#xff0c;无法同时处理多个任务&#xff0c;响应慢&#xff0c;影响…

小红书三面被问 RAG 原理,秒挂…

最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球…

MySQL高阶2082-富有客户的数量

目录 题目 准备数据 分析数据 题目 编写解决方案找出 至少有一个 订单的金额 严格大于 500 的客户的数量。 准备数据 Create table If Not Exists Store (bill_id int, customer_id int, amount int)Truncate table Storeinsert into Store (bill_id, customer_id, amoun…

openpnp - 图像传送方向要在高级校正之前设置好

文章目录 openpnp - 图像传送方向要在高级校正之前设置好笔记END openpnp - 图像传送方向要在高级校正之前设置好 笔记 图像传送方向和JOG面板的移动控制和实际设备的顶部摄像头/底部摄像头要一致&#xff0c;这样才能和贴板子时的实际操作方向对应起来。 设备标定完&#xf…

(C语言贪吃蛇)16.贪吃蛇食物位置随机(完结撒花)

目录 前言 修改方向 修改内容 效果展示 两个新的问题&#x1f64b; 1.问题1 2.问题2 代码如下&#xff1a; 前言 我们上一节实现了贪吃蛇吃食物身体节点变长&#xff0c;但是食物的刷新位置不是随机的&#xff0c;并且初始化几次后食物就刷不见了&#xff0c;本节我们就来…

【Linux】进程地址空间、环境变量:从理论到实践(三)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 &#x1f680; 前言一&#xff1a;&#x1f525; 环境变量 &#x1f95d; 基本概念&#x1f95d; 常见环境变量&#x1f95d; 查看环境变量方法 二&#xff1a;&#x1f525; 测试 &…

Stable Diffusion绘画 | 插件-Deforum:动态视频生成(中篇)

本篇文章重点讲解参数最多的 关键帧 模块。 「动画模式」选择「3D」&#xff1a; 下方「运动」Tab 会有一系列参数&#xff1a; 以下4个参数&#xff0c;只有「动画模式」选择「2D」才会生效&#xff0c;可忽略&#xff1a; 运动 平移 X 让镜头左右移动&#xff1a; 大于0&a…

JavaSE——面向对象练习题

1.对象数组排序 定义一个Person类{name,age,job}&#xff0c;初始化Person对象数组&#xff0c;有3个person对象&#xff0c;并按照age从小到大进行冒泡排序&#xff1b;再按照name的长度从小到大进行选择排序。 public class HomeWork01 {public static void main(String[] a…

基于spring boot的篮球论坛系统

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…

基于拥堵模型的轻量级平台公交室内情况监控系统

论文标题&#xff1a;Bus Indoor Situation Monitoring System Based on Congestion Model Using Lightweight Platform 作者信息&#xff1a;Dong Hyun Kim, Yun Seob Kim, 和 Jong Deok Kim* 所属机构&#xff1a;Pusan National University, Department of Computer Scienc…

Linux·环境变量与进程地址空间

1. 命令行参数 各位可能见过main函数也是有参数的&#xff0c;只是我们平时写的代码都比较简单&#xff0c;用不到main函数的参数&#xff0c;下面我们看一下main函数的参数是什么又是怎么用的 我们看这样一段代码 其编译运行后的效果是这样的 我们将main函数后面的那两个参数叫…

排序算法剖析

文章目录 排序算法浅谈参考资料评价指标可视化工具概览 插入排序折半插入排序希尔排序冒泡排序快速排序简单选择排序堆排序归并排序基数排序 排序算法浅谈 参考资料 数据结构与算法 评价指标 稳定性&#xff1a;两个相同的关键字排序过后相对位置不发生变化时间复杂度空间复…

MyBatisPlus——学习笔记

MyBatisPlus 一、导入依赖 <!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- MySql --><de…

C++基础(7)——STL简介及string类

目录 1.STL简介 1.1什么是 1.2STL的历史版本 1.3STL的六大组件 ​编辑 1.4有用的网址 2.string类 2.1string的多种定义方式 2.2string的插入 2.2.1尾插&#xff08;push_back&#xff09; 2.2.2insert插入 2.3拼接&#xff08;append&#xff09; 2.4删除 2.4.1尾…

CoRL 2024 麻省理工学院提出T3触觉Transformer,打破触觉感知的壁垒,重塑未来机器人

在智能机器人领域&#xff0c;触觉感知的研究正逐渐成为关注的焦点。然而&#xff0c;如何让机器人通过触觉更智能地感知和操作&#xff0c;依然是一个未解决的挑战。基于相机的触觉感知是一种通过在软弹性体下嵌入相机来捕获与环境的细粒度交互的感知方法&#xff0c;是最流行…

Java报错输出的信息究竟是什么?

Java报错输出的信息究竟是什么&#xff1f; 本篇会带大家了解一下java运行时报错输出的信息内容&#xff0c;简单学习一下虚拟机内存中Java虚拟机栈的工作方式以及栈帧中所存储的信息内容 异常信息 当你的程序运行报错时&#xff0c;你是否会好奇打印出来的那一大坨红色的究竟…

搜索引擎相关的一段实习经历

0 前言 就是跟搜索相关的一段经历。主要工作就是建立倒排索引库相关的一些简单内容。 又翻到了以前的工作&#xff0c;权作纪念。 就是简单的封装cpp的库供python语言调用。 反正就是很多版本问题等等吧各种鬼问题。 我感觉这个思路可能还是待考证。 跨语言的调用我感觉还是不…

泛型编程--模板【C++提升】(特化、类属、参数包的展开、static、模板机制、重载......你想知道的全都有)

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; C系列语法知识_Stark、的博客-CSDN博客 其它专栏&#xff1a; 数据结构与算法_Stark、的博客-CSDN博客 C系列项目实战_Stark、的博客-CSDN博客 座右铭&#xff1a;梦…