<Effective C++>读书摘要--Ctors、Dtors and Assignment Operators<二>

<Item 9> Never call virtual functions during construction or destruction

1、you shouldn‘t call virtual functions during construction or destruction, because the calls won‘t do what you think, and if they did, you‘d still be unhappy. If you‘re a recovering Java or C# programmer, pay close attention to this Item, because this is a place where those languages zig, while C++ zags.java可以在构造函数中调用子类函数,但是子类成员变量此时没有初始化。

2、During base class construction, virtual functions never go down into derived classes. Instead, the object behaves as if it were of the base type. Informally speaking, during base class construction, virtual functions aren‘t.

3、It‘s actually more fundamental than that. During base class construction of a derived class object, the type of the object is that of the base class. Not only do virtual functions resolve to the base class, but the parts of the language using runtime type information (e.g., dynamic_cast (see Item 27) and typeid) treat the object as a base class type. An object doesn‘t become a derived class object until execution of a derived class constructor begins.

Upon entry to the base class destructor, the object becomes a base class object, and all parts of C++ — virtual functions, dynamic_casts, etc., — treat it that way.

4、不小心在构造函数或者析构函数中间接调用虚函数是C++的常见错误,因此最好在编码规范中严格进行限制。

class Transaction {

public:
  Transaction()
  { init(); }                                      // call to non-virtual...

  virtual void logTransaction() const = 0;
  ...

private:

  void init()
  {
    ...
    logTransaction();                              // ...that calls a virtual!
  }
};

可以在派生类中定义必要的static函数向基类构造函数传递必要的信息

class Transaction {

public:
  explicit Transaction(const std::string& logInfo);
  void logTransaction(const std::string& logInfo) const;   // now a non-
                                                           // virtual func
  ...
};

Transaction::Transaction(const std::string& logInfo)
{
  ...
  logTransaction(logInfo);                                // now a non-
}                                                         // virtual call

class BuyTransaction: public Transaction {
public:
 BuyTransaction( parameters )
 : Transaction(createLogString( parameters ))             // pass log info
  { ... }                                                 // to base class
   ...                                                    // constructor
private:
  static std::string createLogString( parameters );
};

Using a helper function to create a value to pass to a base class constructor is often more convenient (and more readable) that going through contortions in the member initialization list to give the base class what it needs.

5、Things to Remember

  • 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.
时间: 2024-12-26 17:23:10

<Effective C++>读书摘要--Ctors、Dtors and Assignment Operators<二>的相关文章

&lt;Effective C++&gt;读书笔记--Ctors、Dtors and Assignment Operators

<Item 5> Know what functions C++ silently writes and calls 1.If you don't declare them yourself, compilers will declare their own versions of a copy constructor, a copy assignment operator, and a destructor. Furthermore, if you declare no constructo

&lt;Effective C++&gt;读书摘要--Resource Management&lt;一&gt;

1.除了内存资源以外,Other common resources include file descriptors, mutex locks, fonts and brushes in graphical user interfaces (GUIs), database connections, and network sockets. Regardless of the resource, it's important that it be released when you're fini

Effective STL读书摘要(一)

一直在用STL,认为对STL也有一些理解,比如比较函数怎么写,什么情况下用什么容器效率高,但是当你读过Effective STL之后才知道这远远不够,之前的代码还有很多可以优化的空间,下面我会罗列一些映像比较深的点,比较偏向代码因为这样可以方便以后的调用.这里是到Item29,余下的留下次看. 1) 检查容器是否为空 if(c.empty()){}   better than if(c.size()==0){} 2)如果能用批量操作函数就不要用循环来做 批量操作可以提高效率,要有能用批处理尽量批

&lt;Effective C++&gt;读书摘要--Designs and Declarations&lt;三&gt;

<Item 22> Declare data members private 1.使数据成员private,保持了语法的一致性,client不会为访问一个数据成员是否需要使用括号进行函数调度,还是不使用括号直接访问成员而纠结. 2.使数据成员private,if you use functions to get or set its value, you can implement no access, read-only access, and read-write access. Heck

&lt;Effective C++&gt;读书摘要--Inheritance and Object-Oriented Design&lt;一&gt;

1. 3.

&lt;Effective C++&gt;读书摘要--Designs and Declarations&lt;二&gt;

<Item 20> Prefer pass-by-reference-to-const to pass-by-value 1.By default, C++ passes objects to and from functions by value (a characteristic it inherits from C). Unless you specify otherwise, function parameters are initialized with copies of the

&lt;Effective C++&gt;读书摘要--Templates and Generic Programming&lt;一&gt;

1.The initial motivation for C++ templates was straightforward: to make it possible to create type-safe containers like vector, list, and map. Ultimately, it was discovered that the C++ template mechanism is itself Turing-complete: it can be used to

Effective Java2读书笔记-创建和销毁对象(二)

第3条:用私有构造器或者枚举类型强化Singleton属性 这一条,总体来说,就是讲了一个小技巧,将构造器声明为private,可以实现单例.具体有以下几种实现的方式. ①最传统的单例实现模式,可能有很多变种,核心思想是私有化构造器. public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton(){}; public static Singleton g

Effective C++读书笔记之十二:复制对象时勿忘其每一个成分

Item 12:Copy all parts of an object 如果你声明自己的copying函数,意思就是告诉编译器你并不喜欢缺省显示中的某些行为.而编译器会对"你自己写出copying函数"做出一种复仇的行为:既然你拒绝它们为你写出copying函数,如果你的代码不完全,它们也不会告诉你.结论很明显:如果你为class添加一个成员变量,你必须同时修改copying函数.如果你忘记,编译器不太可能提醒你. 一下提供一种正确的模版: class Date{...}; class