初始化列表

2023-09-20 16:22:49

目录

必须在初始化列表初始化的条件:

explicit

多参数强制类型转换

 静态成员

​编辑

 对于静态成员变量需要在构造函数里初始化吗?

静态成员函数:

题目1:

求1+2+3+...+n_牛客题霸_牛客网 (nowcoder.com)

要求类对象只能在栈上:


必须在初始化列表初始化的条件:

1:const修饰的成员变量(只有一次初始化的机会,发生在定义的时候,也就是初始化列表

2:引用:(要变成其他变量的别名,只有一次初始化的机会,发生在定义,也就是初始化列表。

3:自定义类型成员(且该类没有默认构造)

例如:

#include<iostream>
using namespace std;
class A
{
public:
	A(int a)
	{
		_a = a;
	}
private:
	int _a;
};
class B
{
public:
	B()
	{

	}
private:
	int _b;
	A a;
};

我们不运行也会报错 :如果没有在初始化列表中写的话,对于自定义类型A会调用其默认构造,因为类A没有默认构造,所以报错。

 总结:

explicit

class Date
{
public:
	Date(int year)
		:_year(year)
	{}
	Date& operator=(const Date&d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2022);
	Date d2 = 2022;
	return 0;
}

隐式类型转换。

 

类比这里:

把整型i传递给一个临时变量,该临时变量的类型是double,再把该临时变量赋值给d。 

 

 

这里也是同样,把2022强制类型转换为Date类型传递给临时变量,再把该临时变量传递给d5. 

这里无法优化:这里是引用,必须用2022先构造一个对象,再用该对象引用。

explicit Date(int year)
		:_year(year)
	{}

我们在构造函数前面加上了explicit,就不会发生这些隐式类型转换:

Date(int year,int month=1,int day=1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

 这种半缺省,只用传一个参数的也支持隐式类型转换。

全缺省的也可以。

多参数强制类型转换

class Date
{
public:
	 Date(int year,int month,int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	Date& operator=(const Date&d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	/*Date d1(2022);
	Date d2 = 2022;
	const Date&d5 = 2022;*/
	Date d1 = { 2022, 10, 12 };
	Date d2(2022, 10, 12); 
	return 0;
}

int main()
{
	/*Date d1(2022);
	Date d2 = 2022;
	const Date&d5 = 2022;*/
	Date d1 = { 2022, 10, 12 };
	Date d2(2022, 10, 12); 
	const Date&d3 = { 2022, 10, 13 };
	return 0;
}

 静态成员

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		;
	}
private:
	int _a;
};
int main()
{
	A aa1(1);
	A aa2 = 2;
	return 0;
}

我们想要计算一共创建了多少个A类的对象。

int N = 0;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		+ +N;
	}
	A(const A&aa)
		:_a(aa._a)
	{
		++N;
	}
private:
	int _a;
};
int main()
{
	A aa1(1);
	A aa2 = 2;
	cout << N << endl;
	return 0;
}

只有构造和拷贝构造可以创建对象:

int N = 0;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		++N;
	}
	A(const A&aa)
		:_a(aa._a)
	{
		++N;
	}
private:
	int _a;
};
int main()
{
	A aa1(1);
	A aa2 = 2;
	A aa3 = aa1;
	cout << N << endl;
	return 0;
}

int N = 0;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		++N;
	}
	A(const A&aa)
		:_a(aa._a)
	{
		++N;
	}
private:
	int _a;
};
void f(A aa)
{

}
int main()
{
	A aa1(1);
	A aa2 = 2;
	A aa3 = aa1;
	cout << N << endl;
	f(aa1);
	cout << N << endl;
	return 0;
}

验证了传值传参就是拷贝构造。 

int N = 0;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		++N;
	}
	A(const A&aa)
		:_a(aa._a)
	{
		++N;
	}
private:
	int _a;
};
void f(A aa)
{

}
A f1()
{
	A aa;
	return aa;
}
int main()
{
	A aa1(1);
	A aa2 = 2;
	A aa3 = aa1;
	cout << N << endl;
	f(aa1);
	cout << N << endl;
	f1();
	cout << N << endl;
	return 0;
}

传值返回也是一次拷贝构造。 

尽量避免使用全局变量:

全局变量在哪里都可以修改。

 类里的静态受到类域的限制。

#include<iostream>
using namespace std;

class A
{
public:
	A(int a=1)
		:_a(a)
	{
		;
	}
private:
	int _a;
	static int N;
};
int main()
{
	A aa1(1);
	A aa2 = 2;
	A aa3 = aa1;
}

aa1和aa2中有静态成员变量N吗?

总结:静态成员变量不存在于类对象里,存在于静态区。 

 对于静态成员变量需要在构造函数里初始化吗?

答:不需要,因为静态成员变量是每一个对象都共享的,每一次构造都对静态成员都会对静态成员变量进行修改。

静态成员变量的定义:

在全局定义,需要加上类域。

 只能在类里面使用静态成员变量。

静态成员变量的生命周期是全局的,作用域受类域限制 

 当静态成员变量是公有的时候,也是可以在类外面访问的

#include<iostream>
using namespace std;
int A::N = 0;
class A
{
public:
	A(int a=1)
		:_a(a)
	{
		N++;
	}
private:
	int _a;
public:
	static int N;
};
int main()
{
	A aa1(1);
	A aa2 = 2;
	A aa3 = aa1;
	cout << A::N << endl;
	cout << aa1.N << endl;
}

对于静态成员变量为私有的情况,设置一个成员函数取出静态成员变量。

int GetN()
	{
		return N;
	}

静态成员函数:

如果我们想得到静态成员变量,使用静态成员函数没有对象也可以调用。

 

 静态成员函数只能访问静态成员(没有this指针)

题目1:

求1+2+3+...+n_牛客题霸_牛客网 (nowcoder.com)

class Sum
{
    public:
    Sum()
    {
        _ret+=_add;
        _add++;
    }
    static int GetRet()
    {
        return _ret;
    }
    private:
    static int _ret;
    static int _add;
};
int Sum::_ret=0;
int Sum::_add=1;
class Solution {
public:
    int Sum_Solution(int n) {
        Sum A[n];
        return Sum::GetRet();
    }
};

要求类对象只能在栈上:

class A
{
public:
	A(int a =0)
		:_a(a)
	{
	}
private:
	int _a;
};

class A
{
public:
	A GetObj(int a = 0)
	{
		A aa(a);
		return aa;
	}
	private:
	A(int a =0)
		:_a(a)
	{
	}
private:
	int _a;
};
int main()
{
	A aa3 = GetObj();
	return 0;
}

我们要调用函数GetObj,就需要先创建对象,我们要创建对象,就得先调用函数,产生矛盾。

class A
{
public:
	static A GetObj(int a = 0)
	{
		A aa(a);
		return aa;
	}
	private:
	A(int a =0)
		:_a(a)
	{
	}
private:
	int _a;
};
int main()
{
	A aa3 = A::GetObj();
	return 0;
}

我们可以用静态函数,静态函数不需要对象也可以调用。

更多推荐

XREAL 联合创始人吴克艰谈AR:下一代计算平台及其关键技术

//编者按:一种行业观点是,AR或是未来十年、三十年的革命性技术,是下一代计算平台。近半个世纪,我们总能听到苹果在AR行业的创新动作,开辟了新的硬件范式。AR/VR行业为苹果不断欢呼的同时,激发了人们的好奇心——究竟,人类在戴上AR眼镜的那一瞬间,感知与交互从二维平面延伸到三维空间,科幻片场景触手可及之时,和世界的交互

Android studio 断点调试、日志断点

目录参考文章参考文章1、运行调试2、调试操作3、断点类型行断点的使用场景属性断点的使用场景异常断点的使用场景方法断点的使用场景条件断点日志断点4、断点管理区参考文章参考文章1、运行调试开启Debug调试模式有两种方式:DebugRun:直接以Debug模式运行APP,该模式的优点是可以调试程序启动相关的代码,例如App

Spring基础(2w字---学习总结版)

目录一、Spirng概括1、什么是Spring2、什么是容器3、什么是IoC4、模拟实现IoC4.1、传统的对象创建开发5、理解IoC容器6、DI概括二、创建Spring项目1、创建spring项目2、Bean对象2.1、创建Bean对象2.2、存储Bean对象(将Bean对象注册到容器中)2.3、获取Bean对象【1

计算机网络(二):TCP篇

文章目录1.TCP头部包含哪些内容?2.为什么需要TCP协议?TCP工作在哪一层?3.什么是TCP?4.什么是TCP连接?5.如何唯一确定一个TCP连接呢?6.UDP头部大小是多少?包含哪些内容?7.TCP与UDP的区别?9.TCP和UDP可以使用同一个端口吗?10.TCP三次握手过程是怎样的?11.如何在Linux系

笔试面试相关记录(5)

(1)给定一个字符串,含有大写、小写字母,空格,数字,需要将其变为满足如下条件:所有的数字需要换成空格,并且字符串的头尾不包含空格,且整个字符串不包含连续的两个空格。(2)给定n,k,L,R,接下拉n个数字,要从中选出某个序列,这个序列满足如下条件:对于整个数组中的任意的k个连续的子数组,所选出的子序列必须包含子数组中

Linux网络编程(TCP状态转换关系)

文章目录前言一、TCP状态转换图二、TCP连接状态转换解析三、TCP断开状态转换解析四、为什么需要有2MLS时长总结前言本篇文章来讲解一下TCP的状态转换关系,学习这个状态转换关系对于我们深入了解网络编程是非常有必要的。一、TCP状态转换图二、TCP连接状态转换解析客户端状态转换:1.CLOSED->SYN-SENT:

【Linux】网络编程套接字(C++)

目录一、预备知识【1.1】理解源IP地址和目的IP地址【1.2】认识端口号【1.3】理解"端口号"和"进程ID"【1.4】理解源端口号和目的端口号【1.5】认识TCP协议【1.6】认识UDP协议二、网络字节序【2.1】socket编程接口【2.1.1】socketAPI【2.1.2】bindAPI【2.1.3】list

单片机论文参考:1、基于单片机的电子琴

摘要随着社会的发展进步,音乐逐渐成为我们生活中很重要的一部分,有人曾说喜欢音乐的人不会向恶。我们都会抽空欣赏世界名曲,作为对精神的洗礼。本论文设计一个基于单片机的简易电子琴。电子琴是现代电子科技与音乐结合的产物,是一种新型的键盘乐器。它在现代音乐扮演着重要的角色,单片机具有强大的控制功能和灵活的编程实现特性,它已经溶入

深度学习-偏导数复习

文章目录前言1.偏导数2.偏导数概念1.对x的偏导数2.对y的偏导数3.多元函数偏导数4.如何计算偏导数1.二元函数的偏导数2.复杂函数的偏导数3.分段函数1.分界点的偏导数5.偏导数与连续之间的关系6.偏导数的几何意义7.高阶偏导数1.定义2.高阶偏导数例题(二阶偏导数)3.全微分1.偏增量定义2.全增量定义3计算方

多线程设计模式【多线程上下文设计模式、Guarded Suspension 设计模式、 Latch 设计模式】(二)-全面详解(学习总结---从入门到深化)

目录多线程上下文设计模式Balking设计模式DocumentAutoSaveThreadDocumentEditThreadGuardedSuspension设计模式什么是GuardedSuspension设计模式GuardedSuspension的示例Latch设计模式TwoPhaseTermination设计模式

商城免费搭建之java商城 开源java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1.涉及平台平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务)2.核心架构SpringCloud、SpringBoot、Mybatis、Redis3.前端框架VUE、Uniapp、Bootstrap/H5/CSS3、IOS、Android、小程

热文推荐