1)委托构造函数解释:通过一个构造函数,调用其他的构造函数,完成类成员的初始化。
作用:使代码简洁;
注意事项:
1)可以使链状初始化,不可以是环状初始化;
2)委托构造务必要写到构造函数初始化列表中,不可以写到相关的构造函数中,防止形参重复定义;
相关的案例代码如下图所示:
上图中,如果按1定义对象,则1的构造函数会调用2,进而2的构造函数调用1,完成成员初始化;
2)继承构造函数的应用,主要用的是using 这个关键字,如下代码所示:
#include<string>
#include<iostream>
using namespace std;
class Base
{
public:
Base(int ta,int tb,const string& tstr)
{
this->a = ta;
this->m = tb;
this->str = tstr;
}
void ShowInfo(void)
{
cout<<"a: "<<a<<'\t'<<
"b: "<<m<<'\t'<<
"str: "<<str<<endl;
}
private:
int a;
int m;
string str;
};
class Derive : public Base
{
public:
using Base::Base;
};
int main(void)
{
Derive test1(20,30,"hello world");
test1.ShowInfo();
return 0;
}
结果输出,如下:
a: 20 b: 30 str: hello world
3)统一的数据初始化方式-初始化列表的学习
代码如下:
#include<string>
#include<iostream>
using namespace std;
class Base
{
public:
Base(int ta)
{
a = ta;
}
void show(void)
{
cout<<a<<endl;
}
private:
int a;
};
int main(void)
{
Base base1(52);
base1.show();
//下面的语句执行是这样的:编译器首先去找是否带有参的构造函数,如果有相关的构造函数,
//就会构造一个对象,并把对象赋值给base2;
Base base2 = 28; //隐式类型转换,编译器自动做的
base2.show();
//初始化列表方式
Base base3 = {550}; //这个等号可加可不加
base3.show();
Base base4{444};
base4.show();
int value[]{1, 2, 3}; //初始化列表方法初始化数组
vector<int> v{2, 3, 5};//初始化列表方法初始化动态数组
return 0;
}
函数指针定义
typedef void(*func)(int, int); //记住函数指针的方法,一想到定义函数指针,就想到有个小括号,这样就可以了;
因为如果没有小括号,就变成指针函数了;
- 聚合类型和非聚合类型学习
聚合类型:说白了,就是数组和类;但类必须满足一些条件(聚合类型是可以被初始化列表初始化的):
a)没有用户声明的构造函数;
b)没有私有或保护的非静态数据成员;
c)没有基类;
d) 没有虚函数;
违法上面任何一条,都不是聚合类型;
class A //ok, 类A没有基类
{
private:
static int x; // ok, ‘x’ 是静态数据成员
public:
void fun() { return; } // ok, fun() 是普通的成员函数
};
结论:A 就是一个聚合类型。
5)initializer_list的使用
initializer_list是一种模板类型,主要用于初始化(注意:是相同类型的数据),代码如下:
初始化列表被看成一个对象;
#include<iostream>
using namespace std;
void Fun(std::initializer_list<int> it)
{
auto ptr = it.begin();
for(; ptr != it.end(); ptr++)
cout<<*ptr<<" "<<endl;
}
int main(void)
{
Fun({1,3,5,7,9});
return 0;
}
输出结果:
1
3
5
7
9