19. 成员初始化列表和初始化对象

1.成员初始化列表

2.初始化对象


1.成员初始化列表

csharp 复制代码
1).成员初始化列表简介

成员初始化列表是构造函数的一部分, 位于构造函数参数列表之后, 函数体{}之前, 用:开头

多个成员之间用","分隔, 直接对成员变量进行初始化
csharp 复制代码
#include <string>
using namespace std;

class Person {
private:
    // 成员变量
    int age;
    string name;
    const int id;  // const成员(只读,一旦初始化不可修改)
    int& score;    // 引用成员(必须绑定到一个变量,不能默认初始化)

public:
    // 使用初始化列表(推荐)
    Person(int a, string n, int i, int& s) : age(a), name(n), id(i), score(s) {
        // 函数体为空,成员已在列表中初始化
    }
};

csharp 复制代码
2).为什么必须用初始化列表

C++语法规定, 以下类型的成员变量无法在构造函数体内赋值, 必须在初始化列表中初始化

a.const成员变量: const修饰的变量只读, 必须在创建时(初始化阶段)赋值, 不能后续修改

b.引用成员变量: 引用是变量的别名, 必须在创建时绑定到一个对象, 不能先创建再赋值
csharp 复制代码
class Circle {
private:
    const double PI;  // const成员
    double& radius;   // 引用成员
    double area;

public:
    // 必须在列表中初始化PI和radius
    Circle(double& r) : PI(3.14159), radius(r) {
        area = PI * r * r; // 普通成员可在函数体赋值
    }
};

int main() {
    double r = 5.0;
    Circle c(r); // 引用成员radius绑定到r
    return 0;
}
csharp 复制代码
c.没有默认构造函数的类类型成员: 如果成员是另一个类的对象, 且该类没有默认构造函数, 则

必须通过初始化列表传参构造

d.基类构造函数需要传参: 继承时, 基类没有默认构造函数, 必须在子类初始化列表中调用基类

带参构造
csharp 复制代码
// 基类(无默认构造函数)
class Base {
private:
    int baseVal;
public:
    Base(int val) : baseVal(val) {} // 带参构造,无默认构造
};

// 子类:必须在初始化列表调用基类构造
class Derived : public Base {
private:
    int derVal;
public:
    // 先初始化基类Base,再初始化子类自己的成员
    Derived(int bVal, int dVal) : Base(bVal), derVal(dVal) {}
};
csharp 复制代码
e.避免二次构造, 提升效率

对于类类型成员(如string、vector、自定义类), 初始化列表会直接调用其构造函数创建对

象; 而构造函数体内赋值, 会先调用默认构造函数创建对象, 再调用赋值运算符, 相当于创建 + 

赋值两步操作, 浪费性能
csharp 复制代码
#include <string>
#include <iostream>
using namespace std;

class Test {
public:
    string str;
    // 初始化列表:直接调用string的构造函数(1次构造)
    Test(string s) : str(s) {
        cout << "初始化列表:str直接构造" << endl;
    }
    // 体内赋值:先默认构造str,再赋值(1次默认构造+1次赋值)
    Test(string s, bool flag) {
        str = s;
        cout << "体内赋值:str先默认构造,再赋值" << endl;
    }
};

int main() {
    Test t1("hello");   // 输出:初始化列表:str直接构造
    Test t2("world", true); // 输出:体内赋值:str先默认构造,再赋值
    return 0;
}

csharp 复制代码
3).初始化列表中成员的书写顺序由"成员在类中声明的顺序决定"
csharp 复制代码
class WrongOrder {
private:
    int a;
    int b;
public:
    // 列表中先写b,再写a,但实际先初始化a,再初始化b
    WrongOrder(int val) : a(val1), b(va2) {
    }
};

int main() {
    WrongOrder wo(10); // 输出:a = 随机数, b = 10
    return 0;
}

2.初始化对象

csharp 复制代码
相关推荐
熬夜敲代码的猫13 小时前
C++:让你玩转多态
c++·多态
qeen8713 小时前
【数据结构】二叉树基本概念及堆的C语言模拟实现
c语言·数据结构·c++·
lynnlovemin13 小时前
C++高精度加减乘除算法详解
开发语言·c++·算法·高精度
minji...13 小时前
Linux 网络套接字编程(七)TCP服务端和客户端的实现——网络版本计算器
linux·运维·服务器·网络·c++·tcp/ip·udp
郝学胜-神的一滴13 小时前
epoll 反应堆模型深度拆解:从红黑树到回调闭环,手写高性能回射服务器
linux·运维·服务器·开发语言·c++·unix
小张成长计划..14 小时前
【C++】26:用哈希表封装unordered_set和unordered_map
c++·散列表
故事和你9114 小时前
洛谷-算法2-4-字符串2
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
cpp_250114 小时前
P3374 【模板】树状数组 1
数据结构·c++·算法·题解·洛谷·树状数组
郝学胜-神的一滴14 小时前
干货版《算法导论》 02 :算法效率核心解密
java·开发语言·数据结构·c++·python·算法
stolentime14 小时前
AT_agc061_d [AGC061D] Almost Multiplication Table题解
c++·算法·构造