C++ Primer 笔记10
2013-11-05 08:17
225 查看
1、复制构造函数、赋值操作符和析构函数总称为复制控制(copy control)。
2、复制构造函数可用于:
① 根据另一个同类型的对象显式或隐式初始化一个对象。
② 复制一个对象,将它作为实参传给一个函数。
③ 从函数返回时复制一个对象。
④ 初始化顺序容器中的元素。
⑤ 根据元素初始化式列表初始化数组元素。
3、vector<string> svec(5);
编译器首先使用string默认构造函数创建一个临时值来初始化svec,然后使用复制构造函数将临时值复制到svec的每个元素。
4、合成复制构造函数的行为是,指定逐个成员初始化,将新对象初始化为原对象的副本。
虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制构造函数将复制数组。复制数组时合成复制构造函数将复制数组的每一个元素。
5、复制构造函数就是接受单个类类型应用形参(通常用const修饰)的构造函数。
通过声明(但不定义)private复制构造函数,可以禁止任何复制类类型对象的尝试:
用户代码中的复制尝试将在编译时标记为错误,而成员函数和友元中的复制尝试将在链接时导致错误。
6、赋值操作符: 第一个形参对应着左操作数, 第二个形参对应右操作数。 当操作符为成员函数时,它的第一个操作数隐式绑定到this指针。
赋值操作符也返回对同一类类型的引用。
7、撤销一个容器(不管是标准库容器还是内置数组)时,也会运行容器中的类类型元素的析构函数。 容器中的元素总是按逆序撤销。
8、如果类需要析构函数,则它也需要赋值操作符和复制构造函数,这是一个有用的经验法则,这个法则常称为三法则(rule of
three), 指的是如果需要析构函数,则需要所有这三个复制控制成员。
9、析构函数不能重载, 析构函数与复制构造函数或赋值操作符之间的一个重要区别是, 即使我们编写了自己的析构函数,合成析构函数仍然在我们自己定义的析构函数结束之后运行。
10、定义智能指针类:实现使用计数有两种经典策略,这个所用的方法中,需要定义一个单独的具体类用以封装使用计数和相关指针。
class U_Ptr{
friend class HasPtr;
int *ip;
size_t use;
U_Ptr(int *p): ip(p),
use(1){}
~U_Ptr(){delete ip;}
};
U_Ptr类保存指针和使用计数,每个HasPtr对象将指向一个U_Ptr对象,使用计数将跟踪指向每个U_Ptr对象的HasPtr对象的数目。
使用计数类的使用:
class HasPtr{
public:
HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i){ }
HasPtr(const HasPtr &orig) : ptr(orig.ptr),
val(orig.val) { ++ptr->use;}
HasPtr& operator=(const HasPtr&
rhs)
{
++rhs.ptr->use;
if(--ptr->use == 0)
delete ptr;
ptr = rhs.ptr;
val = rhs.val;
return *this;
}
~HasPtr() {if(--ptr->use == 0) delete ptr;}
private:
U_Ptr *ptr;
int val;
};
11、处理指针成员的另一个完全不同的方法,是给指针成员提供值定义, 复制值型对象时,会得到一个不同的新副本。
2、复制构造函数可用于:
① 根据另一个同类型的对象显式或隐式初始化一个对象。
② 复制一个对象,将它作为实参传给一个函数。
③ 从函数返回时复制一个对象。
④ 初始化顺序容器中的元素。
⑤ 根据元素初始化式列表初始化数组元素。
3、vector<string> svec(5);
编译器首先使用string默认构造函数创建一个临时值来初始化svec,然后使用复制构造函数将临时值复制到svec的每个元素。
4、合成复制构造函数的行为是,指定逐个成员初始化,将新对象初始化为原对象的副本。
虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制构造函数将复制数组。复制数组时合成复制构造函数将复制数组的每一个元素。
5、复制构造函数就是接受单个类类型应用形参(通常用const修饰)的构造函数。
通过声明(但不定义)private复制构造函数,可以禁止任何复制类类型对象的尝试:
用户代码中的复制尝试将在编译时标记为错误,而成员函数和友元中的复制尝试将在链接时导致错误。
6、赋值操作符: 第一个形参对应着左操作数, 第二个形参对应右操作数。 当操作符为成员函数时,它的第一个操作数隐式绑定到this指针。
赋值操作符也返回对同一类类型的引用。
7、撤销一个容器(不管是标准库容器还是内置数组)时,也会运行容器中的类类型元素的析构函数。 容器中的元素总是按逆序撤销。
8、如果类需要析构函数,则它也需要赋值操作符和复制构造函数,这是一个有用的经验法则,这个法则常称为三法则(rule of
three), 指的是如果需要析构函数,则需要所有这三个复制控制成员。
9、析构函数不能重载, 析构函数与复制构造函数或赋值操作符之间的一个重要区别是, 即使我们编写了自己的析构函数,合成析构函数仍然在我们自己定义的析构函数结束之后运行。
10、定义智能指针类:实现使用计数有两种经典策略,这个所用的方法中,需要定义一个单独的具体类用以封装使用计数和相关指针。
class U_Ptr{
friend class HasPtr;
int *ip;
size_t use;
U_Ptr(int *p): ip(p),
use(1){}
~U_Ptr(){delete ip;}
};
U_Ptr类保存指针和使用计数,每个HasPtr对象将指向一个U_Ptr对象,使用计数将跟踪指向每个U_Ptr对象的HasPtr对象的数目。
使用计数类的使用:
class HasPtr{
public:
HasPtr(int *p, int i): ptr(new U_Ptr(p)), val(i){ }
HasPtr(const HasPtr &orig) : ptr(orig.ptr),
val(orig.val) { ++ptr->use;}
HasPtr& operator=(const HasPtr&
rhs)
{
++rhs.ptr->use;
if(--ptr->use == 0)
delete ptr;
ptr = rhs.ptr;
val = rhs.val;
return *this;
}
~HasPtr() {if(--ptr->use == 0) delete ptr;}
private:
U_Ptr *ptr;
int val;
};
11、处理指针成员的另一个完全不同的方法,是给指针成员提供值定义, 复制值型对象时,会得到一个不同的新副本。
相关文章推荐
- C++ Primer 笔记3
- C++ Primer 笔记4
- C++ Primer 笔记5
- C++ Primer 笔记15
- C++ Primer 笔记6
- C++ Primer 笔记16
- C++ Primer 笔记6
- C++ Primer 笔记17
- C++ Primer 笔记7
- C++ Primer 笔记18
- C++ Primer 笔记8
- C++ Primer 笔记19
- C++ Primer 笔记9
- C++ Primer 笔记11
- C++ Primer 笔记20
- C++ Primer 笔记12
- C++ Primer 笔记13
- C++ Primer 笔记14
- C++ Primer 笔记1
- C++ Primer 笔记2