Shifting from C to C++
1. To C++ programmer, for example, a pointer to a pointer looks a little funny. Why, we wonder, wasn’t a reference to a pointer used instead?
const char chr[] = "chenzhenshi&guohonghua";
const char* pchr = chr;
const char** ppchr = &pchr;
const char*& rpchr = pchr; // a reference to a pointer
std::cout << pchr << ' ' << *ppchr << ' ' << rpchr << std::endl;
2. C is a fairly simple language. All it really offers is macros, pointers, structs, arrays, and functions. No matter what the problem is, the solution will always boil down to macros, pointers, structs, arrays, and functions. Not so in C++. The macros, pointers, structs, arrays and functions are still there, of course, but so are private and protected members, function overloading, default parameters, constructors and destructors, user-defined operators, inline functions, references, friends, templates, exceptions, namespaces, and more. The design space is much richer in C++ than it is in C: there are just a lot more options to consider.
Item 1: Prefer const and inline to #define
3. The Item might better be called “prefer the compiler to the preprocessor”.
4. const char* pc;
pc = a1;
std::cout << pc << std::endl;
pc = a2;
std::cout << pc << std::endl;
const char* const pcc = "a const pointer to a const char array";
std::cout << pcc << std::endl;
// error C2166: l-value specifies const object
// pcc = a1; // error!
std::cout << pcc << std::endl;
5. You can define a const variable in a class, but it must be static const, and have a definition in an implementation file.
// .h file
class try_const
{
public:
static const int num;
};
// .cxx file
const int try_const::num = 250;
6. You can get all the efficiency of a macro plus all the predictable behavior and type safety of a regular function by using an inline function.
Template <class type>
Inline const type& max (const type& a, const type& b)
{
Return a > b ? a : b ;
}
7. Given the availability of consts and inlines, your need for the preprocessor is reduced, but it's not completely eliminated. The day is far from near when you can abandon #include, and #ifdef/#ifndef continue to play important roles in controlling compilation. It's not yet time to retire the preprocessor, but you should definitely plan to start giving it longer and more frequent vacations.
Item 2: Prefer <iostream> to <stdio.h>
8. scanf and printf are not type-safe and extensible.
9. In particular, if you #include <iostream>, you get the elements of the iostream library ensconced within the namespace std (see Item 28), but if you #include <iostream.h>, you get those same elements at global scope. Getting them at global scope can lead to name conflicts, precisely the kinds of name conflicts the use of namespaces is designed to prevent.
Item 3: Prefer new and delete to malloc and free
10. The problem with malloc and free(and their variants) is simple : they don’t know about constructors and destructors.
11. free 操作不会调用析构函数,如果指针所指对象本身又分配了内存,则会造成内存丢失。
Item 4: Prefer C++ style comments
Memory Management
12. Memory management concerns in C++ fall into two general camps: getting it right and making it perform efficiently.
Item 5: Use the same form in corresponding uses of new and delete
13. When you use new, two things happen. First, memory is allocated. Second, one or more constructors are called for that memory. When you use delete, two other things happen: one or more destructors are called for the memory, then the memory is deallocated.
14. The standard C++ library includes string and vector templates that reduce the need for built-in arrays to nearly zero.
Item 6: Use delete on pointer members in destructors
15. Speaking of smart pointers, one way to avoid the need to delete pointer members is to replace those members with smart pointer objects like the standard C++ Library’s auto_ptr.
Item 7: Be prepared for out-of-memory conditions
Item 8: Adhere to convention when writing operator new and operator delete
Item 9: Avoid hiding the “normal” form of new
Item 10: Write operator delete if you write operator new
让我们回过头去看看这样一个基本问题:为什么有必要写自己的 operator new 和 operator delete ?答案通常是:为了效率。缺省的 operator new 和 operator delete 具有非常好的通用性,它的这种灵活性也使得在某些特定的场合下,可以进一步改善它的性能。尤其在那些需要动态分配大量的但很小的对象的应用程序里,情况更是如此。