<Effective C++>读书摘要--Resource Management<二>
<Item 15> Provide access to raw resources in resource-managing classes
1、You need a way to convert an object of the RAII class (in this case, tr1::shared_ptr) into the raw resource it contains (e.g., the underlying Investment*). There are two general ways to do it: explicit conversion and implicit conversion.
tr1::shared_ptr and auto_ptr both offer a get member function to perform an explicit conversion, i.e., to return (a copy of) the raw pointer inside the smart pointer object:
int days = daysHeld(pInv.get()); // fine, passes the raw pointer
// in pInv to daysHeld
Like virtually all smart pointer classes, TR1::shared_ptr and auto_ptr also overload the pointer dereferencing operators (operator-> and operator*), and this allows implicit conversion to the underlying raw pointers:
class Investment { // root class for a hierarchy
public: // of investment types
bool isTaxFree() const;
...
};
Investment* createInvestment(); // factory function
std::tr1::shared_ptr<Investment> // have tr1::shared_ptr
pi1(createInvestment()); // manage a resource
bool taxable1 = !(pi1->isTaxFree()); // access resource
// via operator->
...
std::auto_ptr<Investment> pi2(createInvestment()); // have auto_ptr
// manage a
// resource
bool taxable2 = !((*pi2).isTaxFree()); // access resource
// via operator*
...
2、The Font class could offer an explicit conversion function such as get:
class Font {
public:
...
FontHandle get() const { return f; } // explicit conversion function
...
};
Unfortunately, this would require that clients call get every time they want to communicate with the API:
void changeFontSize(FontHandle f, int newSize); // from the C API
Font f(getFont());
int newFontSize;
... changeFontSize(f.get(), newFontSize); // explicitly convert
// Font to FontHandle
Some programmers might find the need to explicitly request such conversions off-putting enough to avoid using the class. That, in turn, would increase the chances of leaking fonts, the very thing the Font class is designed to prevent.
The alternative is to have Font offer an implicit conversion function to its FontHandle:
class Font {
public:
...
operator FontHandle() const { return f; } // implicit conversion function
...
};
That makes calling into the C API easy and natural: 但是隐式转换可能会偷偷造成不想要的转换
Font f(getFont());
int newFontSize;
... changeFontSize(f, newFontSize); // implicitly convert Font
// to FontHandle
3、Often, an explicit conversion function like get is the preferable path, because it minimizes the chances of unintended type conversions. Sometime, however, the naturalness of use arising from implicit type conversions will tip the scales in that direction.但是一切以Item18为原则。Furthermore, some RAII classes combine true encapsulation of implementation with very loose encapsulation of the underlying resource. For example, tr1::shared_ptr encapsulates all its reference-counting machinery, but it still offers easy access to the raw pointer it contains. Like most well-designed classes, it hides what clients don't need to see, but it makes available those things that clients honestly need to access.
4、Things to Remember
APIs often require access to raw resources, so each RAII class should offer a way to get at the resource it manages.
Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.
<Item 16>Use the same form in corresponding uses of new and delete.
5、When you employ a new expression (i.e., dynamic creation of an object via a use of new), two things happen. First, memory is allocated (via a function named operator new—see Items 49 and 51). Second, one or more constructors are called for that memory. When you employ a delete expression (i.e., use delete), two other things happen: one or more destructors are called for the memory, then the memory is deallocated (via a function named operator delete—see Item 51).
6、 In particular, the memory for an array usually includes the size of the array, thus making it easy for delete to know how many destructors to call. The memory for a single object lacks this information. This is just an example, of course. Compilers aren't required to implement things this way, though many do.

7、This is a particularly important rule to bear in mind when you are writing a class containing a pointer to dynamically allocated memory and also offering multiple constructors, because then you must be careful to use the same form of new in all the constructors to initialize the pointer member. If you don't, how will you know what form of delete to use in your destructor?
8、This rule is also noteworthy for the typedef-inclined, because it means that a typedef's author must document which form of delete should be employed when new is used to conjure up objects of the typedef type. For example, consider this typedef:
typedef std::string AddressLines[]; // a person's address has 4 lines,
// each of which is a string
Because AddressLines is an array, this use of new,
std::string *pal = new AddressLines; // note that "new AddressLines"
// returns a string*, just like
// "new string[4]" would
must be matched with the array form of delete:
delete pal; // undefined!
delete [] pal; // fine
delete 和delete []用错了的话,The result is undefined。使用string和vector来避免动态分配数组。
9、Things to Remember
If you use [] in a new expression, you must use [] in the corresponding delete expression. If you don't use [] in a new expression, you mustn't use [] in the corresponding delete expression.
<Item 17>Store newed objects in smart pointers in standalone statements.
10、C++的编译器相比java和C#给予更多语句执行顺序的自由度,exception可能打断正常的执行流程,导致资源泄露
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
processWidget(new Widget, priority()); //不会编译,没有定义好的隐式转换
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
Execute "new Widget".
Call priority.
Call the tr1::shared_ptr constructor.
可以修正如下
std::tr1::shared_ptr<Widget> pw(new Widget); // store newed object
// in a smart pointer in a
// standalone statement processWidget(pw, priority()); // this call won't leak
11、Things to Remember
Store newed objects in smart pointers in standalone statements. Failure to do this can lead to subtle resource leaks when exceptions are thrown.
<Effective C++>读书摘要--Resource Management<二>的更多相关文章
- <Effective C++>读书摘要--Resource Management<一>
1.除了内存资源以外,Other common resources include file descriptors, mutex locks, fonts and brushes in graphi ...
- <Effective C++>读书摘要--Implementations<二>
<Item29> Strive for exception-safe code. 1.如下面的代码 class PrettyMenu { public: ... void changeBa ...
- <Effective C++>读书摘要--Designs and Declarations<一>
<Item 18> Make interfaces easy to use correctly and hard to use incorrectly 1.That being the c ...
- <Effective C++>读书摘要--Inheritance and Object-Oriented Design<二>
<Item 36> Never redefine an inherited non-virtual function 1.如下代码通过不同指针调用同一个对象的同一个函数会产生不同的行为Th ...
- <Effective C++>读书摘要--Designs and Declarations<二>
<Item 20> Prefer pass-by-reference-to-const to pass-by-value 1.By default, C++ passes objects ...
- <Effective C++>读书摘要--Ctors、Dtors and Assignment Operators<二>
<Item 9> Never call virtual functions during construction or destruction 1.you shouldn't call ...
- <Effective C++>读书摘要--Templates and Generic Programming<一>
1.The initial motivation for C++ templates was straightforward: to make it possible to create type-s ...
- <Effective C++>读书摘要--Implementations<一>
1.For the most part, coming up with appropriate definitions for your classes (and class templates) a ...
- <Effective C++>读书摘要--Designs and Declarations<三>
<Item 22> Declare data members private 1.使数据成员private,保持了语法的一致性,client不会为访问一个数据成员是否需要使用括号进行函数调 ...
随机推荐
- mongodb数据的导出和导入
mongo导出表说明: root@827995de7c7f:/# mongoexport --help Usage: mongoexport <options> Export data f ...
- Apache 错误:httpd: Could not open configuration file
神奇的事件,折磨我 电脑关机重启了一下关机之前正常的状态没有任何的异常出现,过了一会开机准备工作.神奇的事情tmd出现了!!!! 打开phpstudy 启动... 嗯?apache亮红报错?? 第一反 ...
- PAT 1001 害死人不偿命的(3n+1)猜想
1001 害死人不偿命的(3n+1)猜想 (15 分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复 ...
- 20145202马超《网络对抗》Exp7 网络欺诈技术防范
本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体有(1)简单应用SET工具建立冒名网站(2)ettercap DNS spoof(3)结合应用两种技术,用DNS spo ...
- MapWinGIS介绍
MapWinGIS是一个不错的开源组件GIS项目,基于微软的COM思想编写,团队的开发人员主要来自爱荷华大学,而且开发团队中还有一位中国人.它的功能类似于AO(当然没有AO那么强大),其核心是一个名字 ...
- Android APP架构设计——MVC、MVP和MVVM介绍
)对于过大的项目,数据绑定需要花费更多的内存. 关于APP的架构设计就介绍到这吧,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/529 ...
- STM32堆栈指针疑问
1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量. ...
- RTL8188EUS之MAC地址烧写(使用利尔达模组)
1. 手上有几个RTL8188EUS的wifi模块,打算把台式机装个无线网卡,但是插上之后发现没有MAC,没办法只能自己去找个烧写MAC的软件.RTL8188内部有个eFuse,用来配置之类的.这个e ...
- Redis系列五 Redis持久化
Redis持久化 一.RDB(Redis DataBase) 1.介绍 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里. Red ...
- leetcode笔记--7 Find the Difference
question: Given two strings s and t which consist of only lowercase letters. String t is generated b ...