「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」
构造函数体的赋值
- 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
- 但,构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
class Date {
public:
Date(int year, int month, int day)
:_year(year),
_month(month),
_day(day)
{}
private:
int _year;
int _month;
int _day;
};
【注意】
- 初始化只能有一次
- 类中的 引用成员变量、
const成员变量、 没有默认构造函数的自定义类型成员 必须放在初始化列表的位置进行初始化。
class A {
public:
A(int a)
:_a(a)
{}
private:
int _a;
};
class B {
public:
B(int a, int n, int ref)
:_aobj(a),
_n(n),
_ref(ref)
{}
private:
A _aobj; // 没有默认构造函数的类
int& _ref; // 引用
const int _n; // const
};
- 不管有没有使用初始化列表,对于自定义类型成员变量,一定会先使用初始化类别初始化。
class A {
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a = 0)" << endl;
}
private:
int _a;
};
class B {
public:
B(int a = 100)
{
cout << "B(int a)" << endl;
}
private:
A _aobj;
};
int main()
{
B b;
return 0;
}
输出
A(int a = 0)
B(int a)
- 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
explicit 关键字
构造函数不仅可以构造初始化对象,对于单个参数的构造函数,还具有类型转换的作用。
class A {
public:
//A(int a = 0)
// :_a(a)
//{
// cout << "A(int a = 0)" << endl;
//}
explicit A(int a = 0)
:_a(a)
{
cout << "A(int a = 0)" << endl;
}
private:
int _a;
};
int main()
{
// A a(100);
A b = 100;
return 0;
}
用一个整形变量给A;类型对象赋值。 实际上编译器会用2019构造一个无名对象,最后用无名对象给b进行赋值。
用
explicit 修饰构造函数,将会禁止单参构造函数的隐式转换。
this 指针
C++编译器给每个 非静态的成员函数 增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户都是透明的,即用户不需要来传递,编译器自动完成。
==特性==
this指针的类型:类类型 * const- 只能在 成员函数 的内部使用
- this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
【问题】
this指针存在哪里?
一般情况下是在栈(形参)。有些编译器会放在寄存器中,如vs2013放在寄存器 ecx 中。
this指针可以为空吗?
class A
{
public:
A(int a = 0) {_a = a; }
void Print() { cout << "Print()" << endl; }
void Num() { cout << _a << endl; }
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
p->Num();
return 0;
}
p->Print();正常运行p->Num();运行崩溃
==分析==
- p虽然是空指针,但是p调用成员函数不会编译报错,因为空指针不是语法错误,编译器检查不出来。
- p虽然是空指针,但是p调用成员函数也不会出现空指针访问。因为成员函数没有存在对象里面。
- 这里会把p作为实参传递给隐藏
this指针。