【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,一经查实,立即删除!

相关文章

paip.最新的c++ qt5.1.1环境搭建跟hello world

paip.最新的c qt5.1.1环境搭建跟hello world 作者Attilax &#xff0c; EMAIL:1466519819qq.com 来源&#xff1a;attilax的专栏 地址&#xff1a;http://blog.csdn.net/attilax 有一段时间没接触c了...今天下载新的qt下来研究一番.. qt的环境搭建有eclipseqtdtmingwqtl…

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

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

PushManager

http://suchandalex.googlecode.com/svn/trunk/beOui/beWe/client/Classes/PushNotificationManager.m转载于:https://www.cnblogs.com/vincent-lu/archive/2012/01/18/2325740.html

krsort_PHP krsort()函数与示例

krsortPHP krsort()函数 (PHP krsort() function) krsort() function is used to sort an associative array in descending order based on the keys, as we know that an associative array contains keys and values, this method sorts an array according to the keys. kr…

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

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

输入输出函数:

一、printf函数&#xff1a;     printf("Hello World!\n");     printf("My age is %d\n",26);     int age 17;     printf("My age is %d\n",age);  %d 或 %i: 带符号 十进制整数。   %o:不带符号 八进制整数。   %x:…

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…

JavaScript中的地图与对象

JavaScript对象与地图 (JavaScript Objects vs Maps) Objects are super popular in JavaScript so its not a term you are hearing for the first time even if youre a novice JS developer. Objects, in general, are a very common data structure that is used very ofte…

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

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

关于$.getJson

这是一个Ajax函数的缩写&#xff0c;这相当于: 123456$.ajax({dataType: "json",url: url,data: data,success: success});数据会被附加到一个查询字符串的URL中&#xff0c;发送到服务器。如果该值的data参数是一个普通的对象&#xff0c;它会转换为一个字符串并使用…

leetcode 1. 两数之和 思考分析

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

六、逻辑回归

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

C# 调用Windows API实现两个进程间的通信

使用Windows API实现两个进程间&#xff08;含窗体&#xff09;的通信http://blog.csdn.net/huangxinfeng/article/details/5513608 从C#下使用WM_COPYDATA传输数据说到Marshal的应用http://www.cnblogs.com/jiangyh-is-me/archive/2006/06/05/417381.html 问题解决&#xff1a…

如何在Golang中返回错误?

In Golang, we return errors explicitly using the return statement. This contrasts with the exceptions used in languages like java, python. The approach in Golang to makes it easy to see which function returns an error? 在Golang中&#xff0c;我们使用return…

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;发布房源、发布论坛帖子可获得…

Eclipse中classpath和deploy assembly的文件位置

classpath的配置信息存储在工程根目录下的.classpath文件 deploy assembly配置信息存储在工程目录下的.settings\org.eclipse.wst.common.component文件中转载于:https://www.cnblogs.com/jubincn/p/3381087.html

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…