C++之构造函数、初始化列表、this指针与常成员函数

1、构造函数可以重载,也可以带有缺省参数

 例如如下这样,都构成重载,编译器会自动选择符合的构造函数

string(void)
string(const sting&str);
string(const string&str,size_t len=5);
string(const char*s);

2、缺省构造函数(无参构造函数)

①如果类中自己没有定义构造函数,那么编译器会为该类提供一个缺省的无参构造函数

->对于基本类型的成员变量不做初始化

->对于类类型的成员变量(成员子对象),会自动调用相应类的无参构造函数来初始化

C++之构造函数、初始化列表、this指针与常成员函数_第1张图片

②如果类中自己定义了构造函数,无论是否有参数,编译器都不会在提供缺省的无参构造函数

C++之构造函数、初始化列表、this指针与常成员函数_第2张图片

 3、类型转换构造函数

explicit:显示的告诉编译器进行显示转换,使用它修饰的构造函数,强制要求类型转换的过程必须显式完成

格式:explicit 类名(源类型){}

例如:

C++之构造函数、初始化列表、this指针与常成员函数_第3张图片

4、拷贝构造函数 

①用一个已经存在的对象作为同类的构造实参,创建新的副本对象,会调用该类的拷贝构造函数

格式 :类名(const 类名&){....}

比如:A a2(a1)这时匹配的是A类的拷贝构造函数

C++之构造函数、初始化列表、this指针与常成员函数_第4张图片

 ②如果一个类没有显示定义拷贝的构造函数,那么编译器会为该类提供一个缺省的拷贝构造函数

-》对于基本类型的成员,按字节复制

-》对类类型的成员变量(成员子对象),自动调用相应类的拷贝构造函数完成拷贝初始化

对象之间的自洽性,会自动寻找洽合的对象

实际上编译器提供的缺省拷贝函数已经很好用了,我们很少自己写拷贝函数

C++之构造函数、初始化列表、this指针与常成员函数_第5张图片

③拷贝构造函数的调用时机 

-》用以定义的对象作为头类对象的构造实参

-》以对象的形式向函数传递参数

-》从函数中返回对象(有可能被编译器优化掉)

C++之构造函数、初始化列表、this指针与常成员函数_第6张图片

 5、 初始化列表

①语法 

格式:类名(形参表):成员变量1(初值),成员变量2(初值)....{...}

C++之构造函数、初始化列表、this指针与常成员函数_第7张图片

 ②大多数情况下,使用初始化列表和原来在构造函数中赋初值结果相同,两种方式可以任选,但是有些特殊场景必须要使用初始化列表

-》如果有类类型的成员变量,并希望以有参的方式对其初始化,则必须采用初始化列表指明需要的构造实参

C++之构造函数、初始化列表、this指针与常成员函数_第8张图片

-》如果有引用型或const修饰的成员变量,必须使用初始化对象来显式的初始化

C++之构造函数、初始化列表、this指针与常成员函数_第9张图片

 注:初始化顺序由声明顺序决定,而与初始化列表无关,所以最好不要使用一个成员变量去初始化另一个成员变量

十五、this指针与常成员函数

1、this指针

①在类中的成员函数(包括构造函数、析构函数)中都会隐藏一个该类类型的指针参数this,这就是为什么成员函数访问类中的其他成员是可以直接访问的原因,本质就是靠this指针来实现的

② 对于普通成员函数,this指向调用对象的地址,如果对于构造函数,this指向正在创建的地址

C++之构造函数、初始化列表、this指针与常成员函数_第10张图片

 ③大多数情况下其实是可以忽略this指针的,在成员函数中直接访问类中的其他成员即可,但是以下几种特殊的情况必须使用this指针

-》区分作用域

当参数变量与成员变量名字相同时,可以通过this指针区分,用this指针访问的一定是成员变量

-》从成员函数返回调用对象本身

-》从类的内部销毁对象自身,堆区new的对象,对象自销毁

C++之构造函数、初始化列表、this指针与常成员函数_第11张图片

-》作为成员的函数实参,实现不同对象的交互,很少使用,因为代码不好维护,不会希望对象与对象之间有过多的依赖和关联,了解一下即可

C++之构造函数、初始化列表、this指针与常成员函数_第12张图片

 2、常成员函数

①在一个类中的普通成员函数参数表后面加const,这个成员函数就是常成员函数(常函数)

格式:返回类型   函数名(形参表)const{函数体}

②常成员函数中this指针是一个常指针,不能在常成员函数中直接修改成员变量的值

注:const实际上修饰了this指针,使它成为了一个常量指针,就无法对只读对象进行修改

C++之构造函数、初始化列表、this指针与常成员函数_第13张图片

 但是我又想改变这个参数怎么办呢?

可以进行去常处理const_cast

C++之构造函数、初始化列表、this指针与常成员函数_第14张图片

也可以在想修改的成员变量前加mutable,也相当于去常

C++之构造函数、初始化列表、this指针与常成员函数_第15张图片

 ③非常对象既可调用非常函数也可以调用常函数,但常对象(包括常指针)只能调用常函数,不可调用非常函数

void func(int*p){}
int main(void){
    const int a=100;
    func(&a);//报错,const int*—>int* 相当于放大权限
}

void func(const int *p){}
int main(void){
    int a=100;
    func(&a);//可以,int*->const int* 缩小权限可以
}

④同一个类中,函数名和参数表相同的成员,常版本和非常版本可以构成重载关系,常对象匹配常版本,非常对象匹配非常版本

C++之构造函数、初始化列表、this指针与常成员函数_第16张图片

你可能感兴趣的:(C++,c++,开发语言)