C++类成员的初始化

[C++深入] --- 类成员初始化的三种方式 初始化列表是在构造函数冒号后对成员进行初始化,这是在成员被分配内存的同时进行的初始化操作。这样避免了成员变量先被默认构造然后再赋值的过程。 阅读详情

1、关于构造函数

1)用构造函数确保初始化

对于一个空类

class Empty { };
编译器会自动声明4个默认函数:构造函数,拷贝构造函数,赋值函数,析构函数(当然,如果不想使用自动生成的函数,就应该明确拒绝),这些生成的函数都是public且inline。构造函数对数据成员进行初始化,使用未初始化值可能导致无法预知的错误,所以,确保每一个构造函数都将每一个成员初始化。

2)为什么构造函数不能有返回值

如果有返回值,要么编译器必须知道怎么处理返回值,要么就客户程序员显式调用构造函数和析构函数,这样,还有安全性么?

3)为什么构造函数不能为虚函数

简单来说,虚函数调用的机制,是知道接口而不知道其准确对象类型的函数,但是创建一个对象,必须知道对象的准确类型;当一个构造函数被调用时,它做的首要事情之一就是初始化它的VPTR来指向VTABLE。

4)构造函数的一个面试题:

#include <iostream>
using namespace std;

class Base 
{
private:
	int i;
public:
	Base(int x)
	{
		i = x;
	}
};

class Derived : public Base
{
private:
	int i;
public:
	Derived(int x, int y)
	{
		i = x;
	}
	void print()
	{
		cout << i + Base::i << endl;
	}
};

int main()
{
	Derived A(2,3);
	A.print();
    return 0;
}
首先,是访问权限问题,子类中直接访问Base::i是不允许的,应该将父类的改为protected或者public(最好用protected)

其次,统计父类和子类i的和,但是通过子类构造函数没有对父类变量进行初始化;此处编译会找不到构造函数,因为子类调用构造函数会先找父类构造函数,但是没有2个参数的,所以可以在初始化列表中调用父类构造函数

最后个问题,是单参数的构造函数,可能存在隐式转换的问题,因为单参数构造函数,和拷贝构造函数形式类似,调用时很可能会发生隐式转换,应加上explicit关键字,修改后如下(程序员面试宝典上只改了前2个)

#include <iostream>
using namespace std;

class Base 
{
protected:
	int i;
public:
	explicit Base(int x)
	{
		i = x;
	}
};

class Derived : public Base
{
private:
	int i;
public:
	Derived(int x, int y):Base(x)
	{
		i = y;
	}
	void print()
	{
		cout << i + Base::i << endl;
	}
};

int main()
{
	Derived A(2,3);
	A.print();
    return 0;
}

2、初始化列表

1)使用初始化列表提高效率

常用的初始化可能如下:

class Student 
{
public:
	Student(string in_name, int in_age)
	{
		name = in_name;
		age = in_age;
	}
private :
	string name;
	int    age;
};
    以前楼主也习惯这么写,可以达到预期效果,不过不是最佳做法,因为在构造函数中,是对name进行赋值,不是初始化,而string对象会先调用它的默认构造函数,再调用string类(貌似是basic_string类)的赋值构造函数;对于上例的age,因为int是内置类型,应该是赋值的时候获得了初值。

    要对成员进行初始化,而不是赋值,可以采用初始化列表(member initialization list)改写为如下:

class Student 
{
public:
	Student(string in_name, int in_age):name(in_name),age(in_age) {}
private :
	string name;
	int    age;
};
    结果与上例相同,不过在初始化的时候调用的是string的拷贝构造函数,而上例会调用两次构造函数,从性能上会有不小提升

    有的情况下,是必须使用初始化列表进行初始化的:const对象、引用对象

2)初始化列表初始顺序

考虑以下代码:

#include <iostream>
using namespace std;

class Base 
{
public:
	Base(int i) : m_j(i), m_i(m_j) {}
	Base() : m_j(0), m_i(m_j) {}
	int get_i() const
	{
		return m_i;
	}
	int get_j() const
	{
		return m_j;
	}

private:
	int m_i;
	int m_j;

};

int main()
{
	Base obj(98);
	cout << obj.get_i() << endl << obj.get_j() << endl;
    return 0;
}
     
输出为一个随机数和98,为什么呢?因为对于初始化列表而言,对成员变量的初始化,是严格按照声明次序,而不是在初始化列表中的顺序进行初始化,如果改为赋值初始化则不会出现这个问题,当然,为了使用初始化列表,还是严格注意声明顺序吧,比如先声明数组大小,再声明数组这样。


总结完毕,望有用

C++成员初始化列表:从初始化与赋值差异到三种必须使用场景详解 在C++面向对象编程中,对象的构造过程涉及数据成员的初始化和赋值两个关键概念。初始化发生在对象创建时,是成员生命周期的起点;而赋值则是在成员已存在后修改其值。这种差异直接影响程序的正确性和效率。成员初始化列表正是C++用于在构造函数体执行前完成真正初始化的语法机制,它直接调用成员的构造函数或设置初始值,避免了默认构造后再赋值的额外开销。对于const常量成员、引用成员以及没有默认构造函数的类类型成员,初始化列表是唯一合法的初始化途径,否则会导致编译错误。理解并正确使用初始化列表,不仅能提升代码性能,更是掌握 阅读详情

相关推荐

汽车OTA安全启动:ECU双验签机制与实战排障指南

汽车OTA升级中的安全启动,本质是基于密码学的信任建立过程,其核心在于ECU上电时对固件镜像的可信验证。该机制依托硬件信任根(Secure Boot ROM),通过RSA/ECDSA等非对称算法完成签名验签,确保升级包未被篡改且来源可信。技术价值体现在防止恶意固件注入、支撑功能安全(ASIL)与信息安全(ISO/SAE 21434)合规。典型应用场景包括4S店远程升级、BMS控制器固件更新及多ECU协同启动。实践中,验签名失败往往源于证书链断裂、Flash布局错位或KeyUsage字段不匹配等底层工程细节,

weixin_29314405的博客 76

c++类成员变量初始化详解

1.类初始化顺序 当类初始化的时候,会调用其构造函数并进行初始化。当对象结束其生命周期,会调用析构函数进行资源回收。 注意类在调用资深构造函数之前,首先会调用其成员变量构造函数并进行初始化,再进入自身构造函数进行初始化。成员变量的声明顺序,就是初始化顺序。后面我们提到的很多情况就跟这个有关系,后面再进行详细解读。 2.声明时初始化 第一种方式是在成员变量声明时初始化。可以看如下示例。 class D { int a = 10; }; 在声明变量a的时候即给其初始化为10。不过注意这种写法是c++1

bitcarmanlee的博客 2万+

【近源攻击】badusb制作

BadUSB是利用伪造HID设备执行攻击载荷的一种攻击方式。HID(Human InterfaceDevice)设备通常指的就是键盘鼠标等与人交互的设备,用户插入BadUSB,就会自动执行预置在固件中的恶意代码。BadUsb插入后,会模拟键盘鼠标对电脑进行操作,通过这些操作打开电脑的命令终端,并执行一条命令,这条命令将从指定网址下载其他代码并于后台静默运行。这些代码功能包括:窃取信息、反弹shell、发送邮件等,从而实现控制目标机或者窃取信息的目的。

qinjilll的博客 2544

C++中类成员初始化方式详细说明

在C++98中,支持了在类声明中使用等号“=”加初始值的方式,来初始化类中静态成员常量。这种声明方式我们也称之为“就地”声明。就地声明在代码编写时非常便利,不过C++98对类中就地声明的要求却非常高。如果静态成员不满足常量性,则不可以就地声明,而且即使常量的静态成员也只能是整型或者枚举型才能就地初始化。而非静态成员变量的初始化则必须在构造函数中进行。 2.构造函数初始化 3.声明时初始化(也称就地初始化,c++11后支持) 在C++98中,支持了在类声明中使用等号“=”加初始值的方式,来初始化类中静态成

weixin_45805339的博客 4394

【学习系列】SAP RAP 17:RAP应用部署集成至Fiori Launchpad 【S4HC Public Edition】

本文详细介绍了在SAP S/4HANA Cloud环境中部署RAP应用集成到Fiori Launchpad的两种方法:使用BAS(SAP Business Application Studio)和VSCode。主要步骤包括:1)在BTP中配置Destination连接ES环境;2)设置信任关系;3)创建BAS开发空间;4)通过Fiori应用生成器部署RAP应用;5)创建IAM App、Business Catalog和Business Role;6)配置Launchpad Space和Pages。文章还提供

DeveloperMrMeng的博客 959

IEC 60747-8 是由国际电工委员会(IEC)制定的标准,标题为《半导体器件 - 分立器件 - 第8部分:场效应晶体管》

IEC 60747-8 是由国际电工委员会(IEC)制定的标准,标题为《半导体器件 - 分立器件 - 第8部分:场效应晶体管》(Semiconductor devices - Discrete devices - Part 8: Field-effect transistors)。该标准详细规定了场效应晶体管(FETs)的测试方法,涵盖静态和动态特性测试,适用于多种类型的FET,包括结型场效应晶体管(JFETs)、绝缘栅场效应晶体管(MOSFETs,增强型和耗尽型)等。3. 标准其他部分(简要概述)

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 571

C/C++ 知识点:类成员初始化方法

https://zhuanlan.zhihu.com/p/384928500

个人技术博客 1684

UG\NX二次开发 判断对象是虚线还是实线

网友提问“怎么区分虚线实线”,这个可以通过函数判断。

王牌飞行员_里海的博客 357

关于C++类成员的初始化

在使用C++编程的过程当中,常常需要对类成员进行初始化,通常的方法有两种: 第一种方法: CMYClass::CSomeClass(){    x=0;    y=1;}第二种方法: CSomeClass::CSomeClass() : x(0), y(1){}     从技术上说,第二种方法比较好,但是在大多数情况下,两者实际上没有什么区别。第二种语法被称为成员初始化列表

风生水起 1240

OpenClaw 2026.3.13 踩坑实录:飞书HTTP协议降级Bug与多版本回归问题汇总

摘要:OpenClaw v2026.3.13存在多个严重回归问题,包括飞书API调用协议意外降级为HTTP导致连接失败(#46100)、本地Gateway诊断矛盾(#45504)及设备配对CLI命令失效等。该版本发布流程本身也存在异常,被迫以v2026.3.13-1标签重新发布。建议飞书用户回退至v2026.3.8稳定版,其他用户谨慎升级。本文详细记录了各Bug现象、影响范围及临时解决方案,并梳理了飞书通道的"多版本回归史",指出其根源在于架构变迁和测试覆盖不足。最后提供了包含配置备份、

Maynor的博客 867

西门子TP900精智系列触摸屏和三菱Q系列PLC以太网通信的组态步骤

西门子TP900精智系列触摸屏和三菱Q系列PLC以太网通信的组态步骤

Robot_PLC_HMI_Automation 6097

C++11类成员的初始化总结

C++为类中提供类成员的初始化列表。 类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员 2.进入构造函数后在构造函数中执行一般计算   1.类里面的任何成员变量在定义时是不能初始化的。   2.一般的数据成员可以在构造函数中初始化。   3.const数据成员必须在构造函数的初始化列表中初始化。   4.static要在类的定义外面初始化。   

AdairJun 2269

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C++类成员初始化

初始化 类的成员变量有三个位置进行初始化: 声明时初始化: 初始化列表初始化( 成员变量初始化的顺序是按照在那种定义的顺序) 以下三种情况下必须使用初始化成员列表 一、需要初始化的数据成员是对象,且该对象不能默认构造。(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。 二、需要初始化const修饰的类成员;(C++11后,声明时初始化也可以) 三、需要初始化引用成员数据; 对于一补充: c++ p

weixin_43626209的博客 1513

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++中类成员初始化规则

C++中类成员初始化规则 类中成员(非静态成员)什么时候被初始化?关于初始化有哪些情况? 成员变量在类实例化时被初始化,通过构造函数来进行初始化。 关于初始化需要注意的地方有三点: 变量在类中有初始值 初始化成员列表 构造函数 类成员初始化的顺序如下: 如果类中没有定义任何的构造函数,则编译器将采用合成的默认构造来初始化类中的成员 如果成员在类中有初始值,则用此初始值进行初始化 如果没有初...

hdadiao的博客 1307

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

C++ 类成员变量初始化

在上面的用法中,我们使用初始化列表初始化_year,_month和_day。例如,常量成员、引用成员和没有默认构造函数的成员都必须使用初始化列表。在C++中,类的成员变量初始化是保证对象正确构建的关键。本文将深入探讨C++类成员变量初始化,重点关注初始化列表的作用、使用场景以及与构造函数体赋值的区别。初始化列表是C++构造函数中的一种语法,用于在构造函数开始执行之前初始化成员变量。由于常量成员在对象构造后不能被修改,必须通过初始化列表赋值。引用必须在对象构造时进行初始化,不能像普通变量一样通过赋值改变。

2301_81489672的博客 784

c++ 类成员变量初始化

首先,说说类成员变量的书写位置:定义类的成员变量必须先写在.h文件中,如果希望初始化,那就在.cpp文件中进行初始化。 注意: 静态变量,如欲初始化,必须在cpp文件内使用 类名::变量名称 的方式初始化。 非静态变量如在.h文件内定以后,如不欲初始化,那么可不在.cpp文件内重新定义,如欲初始化,那么可在.cpp文件内直接使用。例如: 在.h文件中: class R

whoseryourgod的专栏 1824

关于初始化C++类成员

在使用C++编程的过程当中,常常需要对类成员进行初始化,通常的方法有两种: 第一种方法:CMYClass::CSomeClass() { x=0; y=1; } 第二种方法:CSomeClass::CSomeClass() : x(0), y(1) { } 本文将要探讨这两种方法的异同以及如何使用这两种方法。 从技术上说,第二种方法比较好,但是在大多数情况下,两者实际上没...

SurpassLi的专栏 51

C++类成员变量是如何初始化的

初始化方式适用场景示例默认初始化未显式初始化时int x;构造函数初始化列表推荐方式,高效且必须用于const和引用成员构造函数体内赋值不推荐,效率较低y = 20;就地初始化C++11 引入,简洁直观int x = 10;静态成员变量初始化静态成员变量(类外定义)

weixin_45075170的博客 2107

C++ 类成员初始化表

类成员初始化可以在构造函数当中实现,也可以在构造函数的初始化列表当中实现。但高手则一般选择后者,是什么原因呢? // 构造函数当中的实现 CMyObject :: CMyObject (int id, string name) { m_id = id; m_name = name; } // 初始化列表中的实现 CMyObject :: CMyObject(int id, st...

a834595603的博客 383

C++ 类成员的初始化

C++给类成员真·初始化的唯一方式就是成员初始化列表,也即构造函数后面跟冒号的形式。 还有一个假·初始化:直接创建类成员(调用类成员的默认构造函数),在类的构造函数里进行赋值操作。 Warrior::Warrior(int id, int hp, int atk, CampEnum camp,Time&amp; time, vector&lt;Place*&gt;&amp;places) ...

陶晨毅的学习笔记 1001

C++ 类成员的初始化 : 探索C++成员初始化的策略与应用

C++ 类成员的初始化 : 探索C++成员初始化的策略与应用

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1014

C++ 初始化列表初始化类成员

C++ 初始化列表初始化类成员

m0_56077202的博客 425

C++类成员的初始化顺序

注意:类成员初始化的顺序跟成员在类内声明的顺序一致。如果使用多继承,基类被初始化的顺序和它们被派生类继承的顺序一致。类成员初化在构造函数成员初始化列表中的顺序会被忽略。 我们用一个例子来说明。如下: #include using namespace std; class A{  public:  A()  {         cout  } }; class B{

Leatinfy--☆Dream and dreaming☆ 1573

c++类成员变量的初始化顺序以及特殊成员的初始化方法规则

说到类的成员变量的初始化顺序,对于初学者很多容易混淆其顺序,以为简单的按初始表来初始化,其实不然,现在我来详细讲解下类的初始化顺序: 首先由简单开始: class people { public: people():j(1),i(j) { } public: int i; int j; };这个类的初始化结果是什么?也许有人会说结果为:先初始化j=1,再用j初始化i=j=1;所以最

monkey_D_feilong的博客 1909
上一篇: 2012微软暑期实习笔试
下一篇: int_size_is_32(),判断int是否为32位
coder_xia
博客等级 码龄17年 151粉丝 143原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值