【C++grammar】代理构造、不可变对象、静态成员

目录

  • 1、Delegation Constructor(代理构造)
    • 1. What is delegating constructor? (什么是代理构造/委托构造)
    • 2. Avoiding recursive calls of target constructors (避免递归调用目标ctor)
    • 3. 委托构造的好处
  • 2、不可变对象和类
    • 1、如何让类成为“不可变类”
    • 2、特殊情况:指针成员
    • 3、例子
    • 4、不可变对象的“不可变”特征在软件开发中有什么用? 它和thread-safe有什么关系?
  • 3、不可变对象和类
    • 1、声明或定义静态成员
    • 2、静态成员
    • 3、实例成员和静态成员
    • 4、C 中static的作用

1、Delegation Constructor(代理构造)

1. What is delegating constructor? (什么是代理构造/委托构造)

代理构造:一个构造函数可以调用另外的构造函数
在代理构造的时候,被委托的要放在委托的构造函数的初始化列表的位置,不能放在在括号里面。

class A{
public:   A(): A(0){}A(int i): A(i, 0){}A(int i, int j) {num1=i;num2=j;average=(num1+num2)/2;}
private:int num1;int num2;int average;
};

上面例子中,构造函数的调用次序:
A() ->A(int) ->A(int, int)
在这个过程中,形成了所谓的委托构造量,我们最怕的就是出现环形的委托构造。

2. Avoiding recursive calls of target constructors (避免递归调用目标ctor)

递归调用:函数调用其本身
递归调用实际上就是环形调用。

class A{
public:   A(): A(0){}A(int i): A(i, 0){}A(int i, int j): A(){}
private:int num1;int num2;int average;
};

调用次序:
A() -> A(int) ->A(int, int) ->A()

3. 委托构造的好处

让程序员少写代码,使逻辑更加清晰。
执行程序时, 会先执行 一个参数的构造函数, 然后再执行两个参数的构造函数。
大大减少了代码量。

2、不可变对象和类

不可变对象:对象创建后,其内容不可改变,除非通过成员拷贝
不可变类:不可变对象所属的类

1、如何让类成为“不可变类”

1、所有数据域均设置为“私有”属性
2、没有更改器函数
3、也没有能够返回可变数据域对象的引用或指针的访问器
如下:
在这里插入图片描述

2、特殊情况:指针成员

如果只有下面两个条件,是构成不了不可变类的。
1、所有数据域均设置为“私有”属性
2、没有更改器函数
如果getter函数返回指向成员的指针,或者getter函数返回成员的引用。那么通过getter函数也能够修改类成员。
如下:指针指向了类的私有成员,然后我们修改对象的私有数据成员,让对象不成为不可变类。
在这里插入图片描述

所以才要加入第三个条件:没有能够返回可变数据域对象的引用或指针的访问器

3、例子

#include<iostream>
#include<string>
using namespace std;class Date {
private:int year = 2019, month = 1, day = 1;
public:int getYear() { return year; }int getMonth() { return month; }int getDay() { return day; }void setYear(int y) { year = y; }void setMonth(int m) { month = m; }void setDay(int d) { day = d; }Date() = default;Date(int y, int m, int d) :year(y), month(m), day(d) {}std::string toString() {return (std::to_string(year) + '-' + std::to_string(month) + '-' + std::to_string(day));}
};enum class Gender {male,female,
};class Employee {
private:std::string name;Gender gender;Date birthday;
public:void setName(std::string name) { this->name = name; }void setGender(Gender gender) { this->gender = gender; }void setBirthday(Date birthday) { this->birthday = birthday; }std::string getName() { return name; }Gender getGender() { return gender; }Date* getBirthday() { return &birthday; }std::string toString(){return (name +( (gender == Gender::male ? std::string(" male ") : std::string(" female ") )+ birthday.toString()));}//带参构造函数Employee(std::string name,Gender gender,Date birthday):name{name},gender{gender},birthday{birthday}{}//默认构造函数Employee():Employee("Alan",Gender::male,Date(2000,4,1)){}
};//创建Employee对象,然后修改其生日
int main()
{Employee e;//1:settere.setBirthday(Date(1999,1,1));std::cout << e.toString() << std::endl;//2:gettere.getBirthday()->setYear(1998);std::cout << e.toString() << std::endl;return 0;
}

在这里插入图片描述

4、不可变对象的“不可变”特征在软件开发中有什么用? 它和thread-safe有什么关系?

将一些需要共享和协同开发的内容设为不可变对象可以防止内容被他人修改。起到类似const的作用。
详细可以观看这篇文章:
线程安全ThreadSafe

3、不可变对象和类

1、声明或定义静态成员

在类定义中,关键字 static 声明 不绑定到类实例的成员( 该成员无需创建实例化对象即可访问,可以直接用类去访问)在类的内部声明
静态成员的定义是很复杂的。
静态数据成员定义的规则:

(1) 声明为“constexpr”类型的静态数据成员必须 在类中声明 并初始化。自C++17 起,可不在类外定义
(2) 声明为==“inline”(C++17 起) 或者 “const int” == 类型的静态数据成员可以 在类中声明 并初始化;
(3) 其它须在类外 定义并初始化,且不带static 关键字
静态数据成员的定义规则复杂,在类外定义,大部分情况下不会出错

2、静态成员

静态数据成员具有静态存储期(static storage duration)或者C++11线程存储期特性。
静态存储期
对象的存储在程序开始时分配,而在程序结束时解回收。

(1) Only one instance of the object exists ( 只存在对象的一个实例)
(2) 静态存储器对象未明确初始化时会被自动“零初始化(Zero-Initialization)”

3、实例成员和静态成员

一旦实例化了Square(创建了Square的对象),每个对象中都有各自的side成员。这个side成员就叫做实例成员。
而numberOfObjects只存在一个,是由所有的Square对象共享的,叫做静态成员。

class Square {
private:double side;static int numberOfObjects;// ...
public://代理构造,无参构造函数调用有参构造函数Square():Square(1.0){}Square(double side){this->side = side;numberOfObjects++;}// ...
};
//定义静态数据成员,会被零初始化
int Square::numberOfObjects;
int main() {Square s1{}, s2{5.0};
}

调用一次构造函数,numberOfObjects就会+1,所以numberOfObjects可以统计成员数量
在这里插入图片描述

4、C 中static的作用

c语言中static关键字用法详解

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

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

相关文章

RFID模块+WIFI模块+振动传感器+有源蜂鸣器+舵机+Arduino UNO R3所构成的门禁系统模块

该系统模块主要由RFID模块WIFI模块振动传感器有源蜂鸣器舵机Arduino UNO R3组成的门禁系统模块。这里使用舵机充当门锁&#xff0c;用户可以刷卡开门&#xff0c;也可以通过APP控制舵机状态达到开门的效果。若有不法分子想要强行进入室内&#xff0c;对门进行撞击或者人为的破坏…

ESP12E Shield+Arduino UNO R3开发板+DHT11温湿度模块+双色LED灯+有源蜂鸣器+光敏电阻模块+I2CLCD1602液晶显示器所构成的室内检测系统

室内检测系统由ESP12E ShieldArduino UNO R3开发板DHT11温湿度模块双色LED灯有源蜂鸣器光敏电阻模块I2CLCD1602液晶显示器所构成。DHT11温湿度模块获取室内温湿度数据通过I2CLCD1602液晶显示器进行显示&#xff0c;另一方面通过ESP12E Shield将数据上传至云平台。光敏电阻进行捕…

leetcode 202. 快乐数 思考分析(哈希集合与双指针解)

1、题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」定义为&#xff1a;对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和&#xff0c;然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果 可以变为 1&am…

五、线性回归和多项式回归实现

官网API 一、线性回归 针对的是损失函数loss faction Ⅰ、Lasso Regression 采用L1正则&#xff0c;会使得w值整体偏小&#xff1b;w会变小从而达到降维的目的 import numpy as np from sklearn.linear_model import Lasso from sklearn.linear_model import SGDRegresso…

深发展银行编码器(解剖)

电池拆下来&#xff0c;再装上&#xff0c;还能继续用下&#xff0c;不会被重置 转载于:https://www.cnblogs.com/ahuo/archive/2012/01/25/2329485.html

leetcode 1. 两数之和 思考分析

1、题目 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素不能使用两遍。 2、思考分析 双for循环的时间复杂度…

六、逻辑回归

一、何为逻辑回归 逻辑回归可以简单理解为是基于多元线性回归的一种缩放。 多元线性回归y的取值范围在(-∞&#xff0c;∞)&#xff0c;数据集中的x是准确的一个数值。 用这样的一个数据集代入线性回归算法当中会得到一个模型。 这个模型所具备的功能就是当有人给这个模型一个…

leetcode 383. 赎金信 思考分析

题目 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串&#xff0c;判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成&#xff0c;返回 true &#xff1b;否则返回 false。 (题目说明&#xff1a;为了不暴露赎金信字迹&#x…

Numpy(科学计算库)---讲解

本内容来自《跟着迪哥学Python数据分析与机器学习实战》&#xff0c;该篇博客将其内容进行了整理&#xff0c;加上了自己的理解&#xff0c;所做小笔记。若有侵权&#xff0c;联系立删。 迪哥说以下的许多函数方法都不用死记硬背&#xff0c;多查API多看文档&#xff0c;确实&a…

仿安居客好租网房产源码

网站设计简约&#xff0c;大方&#xff0c;清爽开发技术&#xff1a;ASP.NET3.5,SQL2005,VS2008功能简介1、小区&#xff0c;二手房&#xff0c;租房小区发布&#xff0c;编辑&#xff0c;修改功能&#xff0c;图片批量上传2、支持积分&#xff0c;发布房源、发布论坛帖子可获得…

LeetCode 454. 四数相加 II 思考分析

题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) &#xff0c;使得 A[i] B[j] C[k] D[l] 0。 为了使问题简单化&#xff0c;所有的 A, B, C, D 具有相同的长度 N&#xff0c;且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间&am…

【转】Spark源码分析之-scheduler模块

原文地址&#xff1a;http://jerryshao.me/architecture/2013/04/21/Spark%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B-scheduler%E6%A8%A1%E5%9D%97/ Background Spark在资源管理和调度方式上采用了类似于Hadoop YARN的方式&#xff0c;最上层是资源调度器&#xff0c;它负…

【C++grammar】析构、友元、拷贝构造函数、深浅拷贝

目录1、Destructor&#xff08;析构函数&#xff09;在堆和栈(函数作用域与内嵌作用域)上分别创建Employee对象&#xff0c;观察析构函数的行为2、Friend&#xff08;友元&#xff09;1、为何需要友元2、友元函数和友元类3、关于友元的一些问题3、Copy Constructor&#xff08;…

Android PreferenceActivity 使用

我想大家对于android的系统配置界面应该不会陌生吧&#xff0c;即便陌生&#xff0c;那么下面的界面应该似曾相识吧&#xff0c;假若还是不认识&#xff0c;那么也没有关系&#xff0c;我们这一节主要就是介绍并讲解android 中系统配置界面的使用&#xff0c;相信大家看完本节后…

Pandas(数据分析处理库)---讲解

本内容来自《跟着迪哥学Python数据分析与机器学习实战》&#xff0c;该篇博客将其内容进行了整理&#xff0c;加上了自己的理解&#xff0c;所做小笔记。若有侵权&#xff0c;联系立删。 迪哥说以下的许多函数方法都不用死记硬背&#xff0c;多查API多看文档&#xff0c;确实&a…

leetcode 78. 子集 思考分析

题目 给定一组不含重复元素的整数数组 nums&#xff0c;返回该数组所有可能的子集&#xff08;幂集&#xff09;。 说明&#xff1a;解集不能包含重复的子集。 思考分析 画出解空间树。 我们可以发现我们所需要的结果是解空间的所有结点。而我们之前组合问题和分割问题都是…

设计模式读书笔记-----备忘录模式

个人比较喜欢玩单机游戏&#xff0c;什么仙剑、古剑、鬼泣、使命召唤、三国无双等等一系列的游戏我都玩过(现在期待凡人修仙传)&#xff0c;对于这些游戏除了剧情好、场面大、爽快之外&#xff0c;还可以随时存档&#xff0c;等到下次想玩了又可以从刚开始的位置玩起(貌似现在的…

【C++grammar】vector类和字符串字面量

C的vector类 用数组存放数据时&#xff0c;容量大小不可变&#xff0c;vector对象容量可自动增大。 vector的操作&#xff1a; 调用push_back函数时&#xff0c;vector对象的容量可能会增大。 观察下列操作对vector的影响&#xff1a; #include <vector> #include <…

Matplotlib(数据可视化库)---讲解

本内容来自《跟着迪哥学Python数据分析与机器学习实战》&#xff0c;该篇博客将其内容进行了整理&#xff0c;加上了自己的理解&#xff0c;所做小笔记。若有侵权&#xff0c;联系立删。 迪哥说以下的许多函数方法都不用死记硬背&#xff0c;多查API多看文档&#xff0c;确实&a…

Shader Compiler 界面进展1

先从模仿Composer的界面开始. 目前的进展:不用不知道,虽然wxweidgets有很多界面工具如DialogBlocks(DB), 但仍然不好使. 我使用wxAui界面, DialogBlocks并不支持输出其xrc格式, 我猜是wx本身就没有解析wxAui的xrc格式.像wxAuiToolBar或其他wxToolBar, DB工具也不能独立输出xrc.…