我是靠谱客的博主 伶俐悟空,最近开发中收集的这篇文章主要介绍Effective C++读书笔记,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Item 1
1. For simple constants, prefer const objects or enums to #define s.
2. For function-like macros, prefer inline functions to #define s.

Item 2
Use const whever possible
有关iterator比较容易弄错的地方

const  std::vector<int>::iterator iter = vec.begin  //iter acts like a T* const
*iter = 10; //OK, changes what iter points to
++iter; //error! iter is const 
std::vector<int>::const_iterator cIter = vec.begin(); //cIter acts like a const T*
*cIter = 10; //error! *cIter is const
++cIter; //fine, changes cIter

一些函数返回const值,可以避免一些可能的错误。如下:

class Rational {... };
const Rational operator*(const Rational& lhs, const Rational& rhs);
Rational a, b, c;
...
(a * b) = c;  //这种错误就可以避免了.

const Member Functions

Overloaded const member function, 例如

class TextBlock
{
public:
...
    const char& operator[](std::size_t position) const
    {
        return text[position]; //operator[] for const 
                               //objects
    }
    char& operator[](std::size_t position)
    {
        return text[position]; //operator[] for
                               //non-const objects
    }
private:
    std::string text;
  1. Declaring something const helps compilers detect usage errors. const can be applied to objects at an scope, to function parameters and return types, and to member functions as a whole.
  2. Compilers enforce bitwise constness, but you should program using conceptual constness(use mutable)
  3. When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

Item 3
1. Manually initialize objects of built-in type, because C++ only sometimes initializes them itself.
2. In a constructor, prefer use of the member initialization list to assignment inside the body of the constructor. List data members in the initialization list in the same order they’re declared in the class.
3. Avoid initialization order problems across translation units by replacing non-local static objects with local static objects.

Item 4
1. Compilers may implicitly generate a class’s default constructor, copy constructor, copy assignment operator, and destructor.
2. To disallow functionality automatically provided by compilers, declare the corresponding member functions private and give no implementations. Using a base class like Uncopyable is one way to do this

Item 5
1. Polymorphic base classes should declare virtual destructors. If a class has any virtual functions, it should have a virtual destructor.
2. Classed not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors.

Item 6
1. Destructors should never emit exceptions. If functions called in a destructor may throw, the destructor should catch any exceptions, then swallow or terminate the program.
2. If class clients need to be able to react to exceptions thrown during an operation, the class should provide a regular(i.e., non-destructor) function that performs the operation.

Item 7
Don’t call virtual functions during construction or destruction, because such calls will never go to a more derived class than that of the currently executing constructor or destructor.

Item 8
Have assignment operators return a reference to *this.

Item 9
1. Make sure operator= is well-behaved when an object is assigned to itself. Techniques include comparing addresses of source and target objects, careful statment ordering, and copy-and-swap.
2. Make sure that any function operating on more than one object behaves correctly if two of more of the objects are the same.

Item 10
1. Copying functions should be sure to copy all of an object’s data members and all of its base class parts.
2. Don’t try to implement one of the copying functions in terms of the other. Instead, put common functionality in a third function that both call.

Item 11
1. To prevent resource leaks, use RAII(Resource Acquisition Is Initialization) objects that acquire resource in their constructors and release them in their destructors.
2. Two commonly useful RAII classed are TR1::shared_ptr and auto_ptr; tr1::shared_ptr is usually the better choice because its behavior when copied is intuitive. Copying an auto_ptr sets it to null.

Item 12
1. APIs often require access to raw resources, so each RAII class should offer a way to get at the resource it manages.
2. Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.

Item 13
If you use [] in a new expression, you must use [] in the corresponding expression. If you don’t use [] in a new expression, you mustn’t use [] in the corresponding delete expression.

Item 14
Store newed objects in smart pointers in standalone statements. Failure to do this can lead to subtle resource leaks when exceptions are thrown.

Item 15
1. Good interfaces are easy to use and hard to use incorrectly. Your should strive for these characteristics in all your interfaces.
2. Ways to facilitate correct use include consistency in interfaces and behavioral compatibility with built-in types.
3. Ways to prevent errors include creating new types, restricting operations on types, constraining object values, and eliminating client resource management responsibilities.
4. TR1::shared_ptr supports custom deleters. This prevents the cross-DLL problem, can be used to automatically unlock mutexes, etc.

Item 16
1. How should objects of your new type be created and detroyed?
2. How should object initialization differ from object assignment?
3. What does it mean for objects of your new type to be passed by value?
4. What are the restrictions on legal values for your new type?
5. Does your new type fit into an inheritance graph?
6. What kind of type conversions are allowed for your new type?
7. What operators and functions make sense for the new type?
8. What should have access to the members of your new type?
9. What is the “undeclared interface” of your new type?
10. How general is your new type?
11. Is a new type really what you need?

Item 17
1. Prefer pass-by-reference-to-const over pass-by-value. It’s typically more efficient and it avoids the slicing problem.
2. The rule doesn’t apply to built-in types and STL iterator and function object types. For them, pass-by-value is usually appropriate.

Item 18
Never return a pointer or reference to a local stack object, a reference to a heap-allocated object, or a pointer or reference to a local static object if there is a chance that more than one such object will be needed.

Item 19
1. Declare data members private. It gives clients syntactically uniform access to data, affords fine-grained access control, allows invariants to be enforced, and offers class authors implementation flexibility.
2. protected is no more encapsulated than public

Item 20
Prefer non-member non friend functions to member functions. Doing so increases encapsulation, packaging flexibility, and functional extensibility.

Item 21
If you need type conversions on all parameters to a function(including the one pointed to by the this pointer), the function must be a non-member.(比如一些二目运算符)

Item 22
1. Provide a swap member function when std::swap would be inefficient for your type . Make sure your swap doesn’t throw exceptions.
2. If you offer a member swap, also offer a non-member swap that calls the member. For classed(not templates), specialize std::swap, too.
3. When calling swap, employ a using declaration for std::swap, then call swap without namespace qualification.
4. It’s fine to totally specialize std templates for user-defined types, but never try to add something completely new to std.

Item 23
Postpone variable definitions as long as possible. It increases program clarity and improves program efficiency.

Item 24

class Window
{
public:
    virtual void OnSize() {... }
};

class SpecialWindow : public Window
{
public:
    virtual void OnSize()
    {
        static_cast<Window>(*this).OnSize(); //wrong 
                                        //way to call
                                        //base method
        Window::OnSize(); //the right way
    }
};

static_cast(*this).OnSize()会创建一个临时的对象,所做的操作也是在这个临时对象上的。

  1. Avoid casts whenever practical, especially dynamic_cast s in performance-sensitive code. If a design requires casting, try to develop a cast-free alternative.
  2. When casting is necessary, try to hide it inside a function. Clients can then call the function instead of putting casts in their own code.
  3. Prefer C++-style casts to old-style casts. They are easier to see, and they are more specific about what they do.

(未完待续…)

最后

以上就是伶俐悟空为你收集整理的Effective C++读书笔记的全部内容,希望文章能够帮你解决Effective C++读书笔记所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部