首页 > 编程语言 >C++ 类和对象: 初始化列表

C++ 类和对象: 初始化列表

时间:2023-05-10 17:11:50浏览次数:37  
标签:初始化 val int 成员 C++ 列表 构造函数

1. 回顾构造函数

构造函数是6个默认的成员函数之一, 完成对象初始化的工作

而在构造函数中, 有两种初始化对象的方式, 初始化列表和函数体内赋值

首先来回顾一下用函数体内赋值方法进行初始化

#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		// 函数体内赋值
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(1,1,1);
	d1.Print(); 
}

如图, 对对象进行了初始化

那么, 既然有了函数体内赋值初始化的方法, 为什么还需要初始化列表 ?

2. 初始化列表

这是因为有3种成员,无法在构造函数体内进行初始化

1. const修饰的成员变量

2. 引用

3. 没有默认构造函数的自定义类型成员

如下图:

那么, 这3种成员为什么无法在构造函数体内初始化? 

对于const修饰的成员变量, 引用来说, 它们必须在定义的时候进行初始化, 而初始化列表是对象成员定义的地方, 所以它们只能在初始化列表进行初始化

对于没有默认构造函数的自定义类型成员来说, 如果自定义类型成员有默认构造, 编译器会去调用它的默认构造去完成初始化, 如果没有默认构造, 编译器不知道如何对自定义类型成员进行初始化, 就报错了

因为构造函数体内是对对象整体进行初始化的, 而初始化列表是对对象成员进行初始化, 所以只能在初始化列表中手动调用有参构造对自定义类型成员进行初始化

如下例: 

#include <iostream>
using namespace std;
class testcl
{
public:
	testcl(int val)
	{
		_val = val;
	}
private:
	int _val;
};

class cl1
{
public:
	cl1(int val = 1, int ref = 1)
		// 初始化列表
		:_val(val)
		,_ref(ref)
		,t1(3)
	{
	}
private:
	const int _val = 1;
	int& _ref;
	testcl t1;
};
int main()
{
	cl1 obj1(2, 2);
}

如图, 使用初始化列表完成了对 const成员变量, 引用, 无默认构造的自定义类型完成了初始化

照上面的例子来看, 初始化列表可以做到函数体内赋值做不到的事, 那么对对象初始化只用初始化列表就可以, 为什么还需要函数体内赋值?

初始化列表只能解决大部分对象初始化的工作, 还有一些工作只能用函数体内赋值来完成, 如下例

对于返回指针的判断是无法在初始化列表中完成的, 只能在构造函数体内

 

标签:初始化,val,int,成员,C++,列表,构造函数
From: https://www.cnblogs.com/xumu11291/p/17388189.html

相关文章

  • ibatis查询返回java.util.HashMap结果列表
    DAO的实现类中的代码:Java代码returnMapgetItemNames(){ returngetSqlMapClientTemplate().queryForMap("getItemNameMap",null,"key","value");}SqlMap配置文件中的代码:Java代码<resultMapid=map-item-name"class=......
  • C++ return std::move(obj)的效率问题
    在visualstudio2022x32release模式下测得 直接看图即可,可以看出returnstd::move反而会降低性能,而直接返回obj则与直接构造无任何差异。这其实不符合我们对直接返回对象的直觉理解,不过这个和编译器的优化相关,可以详细搜索RVO和NRVO的相关内容。......
  • C++MFC数据库程序设计[2023-05-10]
    C++MFC数据库程序设计[2023-05-10]项目必须使用面向对象程序设计的方法来完成,项目中涉及的数据存取必须由数据库完成,同时程序必须有UI(图形或菜单均可)界面,必须完成数据录入、修改、删除、插入、浏览、查询和排序等功能。是否使用MFC中的对话框、单文档等,由同学们自行决定。即......
  • C++ 类和对象: const关键字
    1.const关键字在C语言中,const关键字用来修饰变量,表示变量的值不能被修改在C++中,const可以修饰变量,也可以用来修饰对象和类成员变量下面先来看一下,const修饰对象使用const修饰的对象d1,调用成员函数报错,这是为什么?那么只要把this指针类型改为constDate*,......
  • 解决在线用户列表和重复登录
    解决在线用户列表和重复登录解决两个问题:1.实现在线用户列表2.当用户在异地登录后,使前一次登录自动退出实现方法:用户登录时,会创建一个session,用于保存用户信息。将所有用户登录时的session值与ID存入ServletContext中,显示在线列表的时候,就从ServletContext中取得......
  • C++ Primer学习笔记——第二章
    第二章变量和基本类型前言数据类型是程序的基础:它告诉我们数据的意义以及我们能在数据上执行的操作。2.1基本内置类型C++定义了包括算术类型(arithmetictype)和空类型(void)在内的基本数据类型。2.1.1算术类型算术类型分为两类:整型和浮点型。具体分类:类型含义最小容......
  • 写C++模板函数的两种形式
    #include<iostream>template<typenameT>autof1(constT&x){std::cout<<x<<std::endl;};autof2=[](constauto&x){std::cout<<x<<std::endl;};intmain(intargc,char**argv){int......
  • C++入门
    C++是面向过程也面向对象的语言,具有预处理器、预处理器指令和宏、模板、对象、封装、继承、多态的特性。1、C++程序的内存通常如何分配?解答:全局数据区:通常存储全局变量、静态数据和常量代码区:所有类成员函数和非成员函数代码栈区:执行函数时分配的局部变量、函数参数、返回......
  • C++求平均值
    #include<iostream>#include<iomanip>usingnamespacestd;intmain(){  doublea[100];doublen=0,m=0;inti=0;  doublec;  for(inti=0;i<100;i++)  {cin>>a[i];  if(a[i]==-1)break; }if(a[0]==18&&a[1]==2){cout<<&quo......
  • C++如何获取网卡地址(跨平台)
    需求:获取电脑网卡的硬件地址。就是Linux下运行ifconfig出来的硬件地址。直接上代码:windows下运行ipconfig/all 显示的物理地址。  头文件:GetMacAddrFunc.h#ifndef__DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__#define__DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__#......