C++ Primer 学习笔记——拷贝控制
2016-03-07 14:54
399 查看
拷贝构造函数
直接初始化:编译器使用普通的函数匹配,来选择与我们提供的参数最匹配的构造函数
拷贝初始化:将右侧的对象拷贝到正在创建的对象中,通常使用拷贝构造函数来完成
调用拷贝构造函数 除了=还有,
将一个对象作为实参传递给一个非引用类型的形参
从一个返回类型为非引用的函数返回一个对象
用花括号列表初始化一个数组中的元素或一个聚合类中的成员
拷贝构造函数的参数必须是引用
返回值被用来初始化调用方的结果
拷贝赋值运算符
operator=
析构函数
~Foo();
无论何时一个对象被销毁,就会自动调用其析构函数
=default
显示的要求编译器生成合成的版本
=delete
阻止拷贝/阻止赋值、
不能删除析构函数,否则无法销毁此类型的对象
行为像值的类
即从底层拷贝值,拷贝指针指向的值(而不是拷贝指针)
行为像指针的类
拷贝指针成员本身而不是他的指向
交换操作
直接初始化:编译器使用普通的函数匹配,来选择与我们提供的参数最匹配的构造函数
拷贝初始化:将右侧的对象拷贝到正在创建的对象中,通常使用拷贝构造函数来完成
调用拷贝构造函数 除了=还有,
将一个对象作为实参传递给一个非引用类型的形参
从一个返回类型为非引用的函数返回一个对象
用花括号列表初始化一个数组中的元素或一个聚合类中的成员
拷贝构造函数的参数必须是引用
返回值被用来初始化调用方的结果
拷贝赋值运算符
operator=
析构函数
~Foo();
无论何时一个对象被销毁,就会自动调用其析构函数
//HasPtr #include<iostream> #include<string> using std::string; class HasPtr { public: HasPtr(const std::string &s = std::string()) :ps(new std::string(s)),i(0){} //HasPtr(const HasPtr& tHasPtr) //{ // ps = new string; // *ps = *(tHasPtr.ps); // i = tHasPtr.i; //} HasPtr(const HasPtr& t) :ps(new string(*(t.ps))), i(t.i){} HasPtr& operator=(const HasPtr& t) { i = t.i; ps = new string; *ps = *(t.ps); } ~HasPtr(){ delete ps; } private: std::string *ps; int i; };
//numbered类。 #include<iostream> using std::cout; using std::endl; class numbered { public: numbered() { mysn++; } numbered(const numbered& t) { cout << "enter" << endl; mysn = ++t.mysn; } static int mysn; }; int numbered::mysn = 0; void f(numbered s) { cout << s.mysn ; } int main() { numbered a, b = a, c = b; //创建b和c时候,适用拷贝构造函数(不论是默认的还是自定义的,) f(a); f(b); f(c); return 0; }
=default
显示的要求编译器生成合成的版本
=delete
阻止拷贝/阻止赋值、
不能删除析构函数,否则无法销毁此类型的对象
//13.18 #include<iostream> #include<string> using namespace std; class Employee { private: string name; int card; static int data; public: Employee(string tname) :name(tname){ data++; card = data; } void print() { cout << name << " " << card << endl; } }; int Employee::data = 1; int main() { Employee c1("sdfa"), c2("fasf"); c1.print(); c2.print(); return 0; }
行为像值的类
即从底层拷贝值,拷贝指针指向的值(而不是拷贝指针)
class HasPtr { public: HasPtr(string &s = string()) :ps(new string(s)){} HasPtr(const HasPtr &s) { ps = new string(*(s.ps));//拷贝底层string(及指针指向的值) i = s.i; } HasPtr operator=(const HasPtr &s); ~HasPtr(){ delete ps; } private: string *ps; int i; }; //赋值运算符必须处理自赋值 HasPtr HasPtr::operator=(const HasPtr &s) { auto newp = new string(*(s.ps)); delete ps;//释放旧内存 ps = newp; i = s.i; return *this; }
行为像指针的类
拷贝指针成员本身而不是他的指向
class HasPtr { public: HasPtr(const string &s = string()) :ps(new string(s)), i(0), use(new size_t(0)){} HasPtr(const HasPtr &s) :ps(s.ps), i(s.i), use(s.use){ ++*use; } HasPtr& operator=(const HasPtr&); ~HasPtr() { --*use; if (use == 0) { delete ps; delete use; } }; private: string *ps; int i; size_t *use; }; //赋值运算符必须处理自赋值 HasPtr& HasPtr::operator=(const HasPtr& s) { ++*s.use; if (--*use == 0) { delete ps; delete use; } ps = s.ps; i = s.i; use = s.use; return *this; }
交换操作
//13.3 #include<iostream> #include<string> using std::string; using std::cout; class HasPtr { public: HasPtr(string &s = string()) :ps(new string(s)){} HasPtr(const HasPtr &s) { ps = new string(*(s.ps));//拷贝底层string(及指针指向的值) i = s.i; } HasPtr operator=(const HasPtr &s); ~HasPtr(){ delete ps; } //HasPtr版本的swap,如果一个类有自己特地的swap函数,调用std::swap(标准库中)就是错误的 friend void swap(HasPtr &, HasPtr &); //在赋值运算符中使用swap,将左侧对象与右侧对象的一个副本进行交换 HasPtr& operator=( HasPtr); private: string *ps; int i; }; //赋值运算符必须处理自赋值 HasPtr HasPtr::operator=(const HasPtr &s) { auto newp = new string(*(s.ps)); delete ps;//释放旧内存 ps = newp; i = s.i; return *this; } inline void swap(HasPtr &h1, HasPtr &h2) { cout << *(h1.ps) << " " << *(h2.ps); using std::swap; swap(h1.ps, h2.ps);//交换指针 swap(h1.i, h2.i); cout << *(h1.ps) << " " << *(h2.ps); } HasPtr& HasPtr::operator=( HasPtr h) { swap(*this, h); return *this; } int main() { string s = "123", s2 = "abc"; HasPtr h1(s), h2(s2); swap(h1, h2); return 0; }
相关文章推荐
- 整数划分算法实现 分治策略
- 全排列算法实现 分治策略
- VC++之Office自动化开发
- C++中,内存5个区
- C++虚函数与纯虚函数用法与区别(转)
- 字符串的前中后缀表达式,以及KMP算法。
- c++primer(第五版) 第十一章 关联容器习题答案
- c++11新特性--decltype auto
- C++——boost:asio的使用
- 转:单片机C语言中的data,idata,xdata,pdata,code
- VS 2008配置cppcheck
- 用C++实现顺序表
- c++类学习
- 孵化001 ---C语言的第一个程序
- Vector的用法
- C++中引用和指针的区别
- C++中的RTTI机制详解
- C++ union enum 探究
- 【c语言】推断一个数是不是2的n次方
- 64位和32位平台下C/C++结构内存对齐