【C++修炼之路】28.新的类功能 您所在的位置:网站首页 std::string赋值 【C++修炼之路】28.新的类功能

【C++修炼之路】28.新的类功能

2023-04-01 03:28| 来源: 网络整理| 查看: 265

C++11之新的类功能前言1. 默认成员函数2. 类成员变量初始化3. 强制生成默认函数的关键字default4.禁止生成默认函数的关键字delete前言

这一篇仍是C++11中新增的内容。

1. 默认成员函数

原来C++类中,有6个默认成员函数:

构造函数析构函数拷贝构造函数拷贝赋值重载取地址重载const 取地址重载

最后重要的是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。

C++11 新增了两个:移动构造函数和移动赋值运算符重载。

针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下:

如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内 置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造 完全类似)如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。

观察代码看看:

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& operator=(const Person& p) { if(this != &p) { _name = p._name; _age = p._age; } return *this; }*/ /*~Person() {}*/ private: cfy::string _name; int _age; }; int main() { Person s1; Person s2 = s1; Person s3 = std::move(s1); Person s4; s4 = std::move(s2); return 0; }

如果打开注释的任意一个或者都打开:

2. 类成员变量初始化

C++11允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化,这个我们在雷和对象默认就讲了,这里就不再细讲了。

3. 强制生成默认函数的关键字default

如果需要写析构函数,此时移动构造就不会默认生成,因此可以使用default强制生成移动构造:

// 以下代码在vs2013中不能体现,在vs2019下才能演示体现上面的特性。 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) :_name(std::forward(p._name)) , _age(p._age) {}*/ //强制生成 Person(Person&& p) = default; /*Person& operator=(const Person& p) { if (this != &p) { _name = p._name; _age = p._age; } return *this; }*/ ~Person() {} private: cfy::string _name; int _age; }; int main() { Person s1; Person s2 = s1; Person s3 = std::move(s1); return 0; }4.禁止生成默认函数的关键字delete

如果能想要限制某些默认函数的生成,在C++98中,是该函数设置成private,并且只声明补丁已,这样只要其他人想要调用就会报错。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。就拷贝构造来说:

c++98的方式:

对于c++98来说,将构造函数写出并放在私有,这可以防止外部调用拷贝构造,但是不能防内部;但在类中只声明不实现,声明为私有同样可以防止内部。

class A { public: A() {} ~A(){ delete[] p;} private: //只声明不实现,声明为私有 C++98 A(const A& aa);//浅拷贝 int* p = new int[10]; };

c++11的方式:(简洁-推荐)

class A { public: A() {} ~A(){ delete[] p;} //c++11 A(const A& aa) = delete; private: int* p = new int[10]; };

c++11通过delete的方式直接就禁掉了拷贝构造的调用。因此通过delete无疑是最好的方式。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有