C++类与对象超详细入门指南
前言
💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!
👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对C++感兴趣的朋友,让我们一起进步!
1. 初始化列表——再谈构造函数
1.1 初始化成员变量的方式
初始化列表 是构造函数中用于初始化类成员变量的一种特殊机制。与在构造函数体中直接赋值不同,初始化列表可以提高效率,尤其是对于某些特定类型的成员变量,它是唯一可行的初始化方式。
1.1.1 构造函数内部赋值 vs 初始化列表
在C++中,我们有两种主要方式来初始化类的成员变量:
-
构造函数内部赋值:在构造函数体内给成员变量赋值。
例如:
class MyClass {
public:
MyClass(int x) {
this->_x = x;// 在构造函数体内赋值
//_x=x;
}
private:
int _x;
};
初始化列表赋值:在构造函数的初始化列表中直接对成员变量进行初始化。
例如:
class A {
public:
A(int x) : _x(x) { // 使用初始化列表赋值
}
private:
int _x;
};
1.1.2 两者的区别
内置类型(如 int):对于内置类型,使用初始化列表和在构造函数体内赋值在效率上几乎没有差别。内置类型没有构造函数,也不会进行隐式初始化(即它们是随机值)。构造函数体内赋值或初始化列表赋值都只进行一次操作。因此,选择哪种方式主要是基于代码的清晰性和一致性。
类类型:对于类类型的成员变量,如果没有使用初始化列表,成员变量会先调用默认构造函数进行初始化,然后在构造函数体内再赋值。这样就相当于进行了两次操作:一次初始化,一次赋值。而使用初始化列表时,成员变量只会被初始化一次,效率更高。
-
特殊情况:某些成员变量,例如常量 (
const
)、引用类型 (reference
) 或没有默认构造函数的对象,必须通过初始化列表进行初始化,否则编译器会报错。
1.1.3 为什么要使用初始化列表
- 效率:如前所述,初始化列表避免了成员变量的二次初始化,特别是在类类型成员中,性能优势更为明显。
- 必要性:某些类型的成员变量,如
const
、引用类型,或没有默认构造函数的类成员,必须通过初始化列表进行初始化,否则编译器无法自动处理这些成员的初始化。
1.1.4 示例
class Time {
public:
Time(int hour) : _hour(hour) {
cout << "Time() called" << endl;
}
private:
int _hour;
};
在这个例子中,Time
类的构造函数使用了初始化列表,将传入的参数 hour
直接赋值给成员变量 _hour
。这样,_hour
在对象构造时就被初始化,而不需要在构造函数体内赋值。
1.2 初始化列表的语法
语法结构:初始化列表的使用方式是在构造函数名后跟一个冒号,接着是一个以逗号分隔的成员变量列表,每个成员变量后面紧跟括号中的初始值或表达式。
基本语法格式:
ClassName(参数列表) : 成员变量1(初始值), 成员变量2(初始值), ... {
// 构造函数体
}
1.2.1 示例:
class Myclass
{
public:
Myclass(int x,int y):_x=x,_y=y{//使用初始化列表初始化成员变量}
private:
int _x;
int _y;
};
1.3 引用成员变量、const成员变量的初始化
引用类型和常量类型等,只能通过初始化列表进行初始化。
1.3.1 引用类型成员初始化
引用类型成员变量在 C++ 中必须在声明时被初始化,不能在构造函数体内赋值,必须使用初始化列表。
class MyClass {
public:
MyClass(int& ref) : _ref(ref) {
// _ref 是引用类型,必须在初始化列表中初始化
}
private:
int& _ref;
};
1.3.2 const成员变量的初始化
class MyClass {
public:
MyClass(int n) : _n(n) {
// _n 是 const 类型,必须在初始化列表中初始化
}
private:
const int _n;
};
1.3.3没有默认构造函数的类类型变量
class Time {
public:
Time(int hour) : _hour(hour) {}
private:
int _hour;
};
class Date {
public:
Date(int year, int month, int day) : _year(year), _month(month), _day(day), _t(12) {
// _t 是 Time 类型,必须在初始化列表中调用 Time 的构造函数
}
private:
int _year;
int _month;
int _day;
Time _t; // Time 没有默认构造函数
};
1.4 成员变量默认值的使用 (C++11)
C++11 引入了成员变量默认值的概念。可以在类的声明中为成员变量提供默认