admin管理员组文章数量:1037775
【C++11】新的类功能
Ⅰ. 默认成员函数
原来 C++
类中,有 6
个默认成员函数:
- 构造函数
- 析构函数
- 拷贝构造函数
- 拷贝赋值重载
- 取地址重载(了解即可)
- const 取地址重载(了解即可)
最后重要的是前 4
个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。
而 C++11
新增了两个:移动构造函数和移动赋值运算符重载。
针对 移动构造函数 和 移动赋值运算符重载 有一些需要注意的点如下:
- 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。
- 如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造完全类似)
- 如果你 提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。
Ⅱ. 类成员变量初始化
C++11
允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化,这个我们在类和对象这里就不再细讲了。
注意这只是声明,不是定义!如果在构造函数中没有给该成员变量赋值的话,那么才会采用这个初始缺省值!
下面举个例子:
代码语言:javascript代码运行次数:0运行复制class A
{
public:
// ...
private:
int x = 10; // 声明缺省值
string str = "liren";
const float ft = 10.3;
};
Ⅲ. 强制生成默认函数的关键字 default
C++11
可以让你更好的控制要使用的默认函数。假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用 default
关键字显示指定移动构造生成。
default
只能修饰类中默认提供的成员函数:无参构造函数、拷贝构造函数、赋值运算符重载函数、析构函数,且该特殊成员函数没有默认参数=default
函数既可以在类内定义, 也可以在类外定义
class Person
{
public:
Person(const char* name = "", int age = 0)
:_name(name)
, _age(age)
{ // 实现省略 }
Person(const Person& p) // 有了拷贝构造,不会默认生成移动构造
:_name(p._name)
,_age(p._age)
{ // 实现省略 }
Person(Person&& p) = default; // 所以利用=default强制使用默认的移动构造
int f() = default; // ❌f不是Person的特殊成员函数
private:
liren::string _name;
int _age;
};
int main()
{
Person s1;
Person s2 = s1;
Person s3 = std::move(s1);
return 0;
}
//运行结果
string(const string& s) -- 深拷贝
string(string&& s) -- 移动资源
Ⅳ. 禁止生成默认函数的关键字 delete
如果能想要 限制某些默认函数的生成,在 C++98
中,是将该函数设置成 private
,并且只声明但不实现,这样只要其他人想要调用就会报错。在 C++11
中更简单,只需在该函数声明加上 =delete 即可,该语法指示编译器不生成对应函数的默认版本,称 =delete
修饰的函数为删除函数。
【C++11】新的类功能
Ⅰ. 默认成员函数
原来 C++
类中,有 6
个默认成员函数:
- 构造函数
- 析构函数
- 拷贝构造函数
- 拷贝赋值重载
- 取地址重载(了解即可)
- const 取地址重载(了解即可)
最后重要的是前 4
个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。
而 C++11
新增了两个:移动构造函数和移动赋值运算符重载。
针对 移动构造函数 和 移动赋值运算符重载 有一些需要注意的点如下:
- 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。
- 如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造完全类似)
- 如果你 提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。
Ⅱ. 类成员变量初始化
C++11
允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化,这个我们在类和对象这里就不再细讲了。
注意这只是声明,不是定义!如果在构造函数中没有给该成员变量赋值的话,那么才会采用这个初始缺省值!
下面举个例子:
代码语言:javascript代码运行次数:0运行复制class A
{
public:
// ...
private:
int x = 10; // 声明缺省值
string str = "liren";
const float ft = 10.3;
};
Ⅲ. 强制生成默认函数的关键字 default
C++11
可以让你更好的控制要使用的默认函数。假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用 default
关键字显示指定移动构造生成。
default
只能修饰类中默认提供的成员函数:无参构造函数、拷贝构造函数、赋值运算符重载函数、析构函数,且该特殊成员函数没有默认参数=default
函数既可以在类内定义, 也可以在类外定义
class Person
{
public:
Person(const char* name = "", int age = 0)
:_name(name)
, _age(age)
{ // 实现省略 }
Person(const Person& p) // 有了拷贝构造,不会默认生成移动构造
:_name(p._name)
,_age(p._age)
{ // 实现省略 }
Person(Person&& p) = default; // 所以利用=default强制使用默认的移动构造
int f() = default; // ❌f不是Person的特殊成员函数
private:
liren::string _name;
int _age;
};
int main()
{
Person s1;
Person s2 = s1;
Person s3 = std::move(s1);
return 0;
}
//运行结果
string(const string& s) -- 深拷贝
string(string&& s) -- 移动资源
Ⅳ. 禁止生成默认函数的关键字 delete
如果能想要 限制某些默认函数的生成,在 C++98
中,是将该函数设置成 private
,并且只声明但不实现,这样只要其他人想要调用就会报错。在 C++11
中更简单,只需在该函数声明加上 =delete 即可,该语法指示编译器不生成对应函数的默认版本,称 =delete
修饰的函数为删除函数。
本文标签: C11新的类功能
版权声明:本文标题:【C++11】新的类功能 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/jiaocheng/1748341599a2288066.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论