
- 《深度探索C++对象模型》(《Inside the C++ object Model》)第五章:
原文:
Given what we know, you should be able to answer the following question: Is it safe to invoke avirtual function of the class within its constructor's member initialization list? Physically, it is alwayssafe when the function is applied to the initialization of a data member of the class. This is because,as we've seen, the vptr is guaranteed to have been set by the compiler prior to the expansion ofthe member initialization list. It may not be semantically safe, however, because the function itselfmay depend on members that are not yet initialized. It is not an idiom I recommend. However, fromthe point of view of the integrity of the vptr, it is a safe operation.
What about when providing an argument for a base class constructor? Is it still physically safe toinvoke a virtual function of the class within its constructor's member initialization list? No. The vptr iseither not set or set to the wrong class. Further, any of the data members of the class that areaccessed within the function are guaranteed to not yet be initialized.
中文翻译:
知道了这些之后,你应该能够回答下面的问题了吧:在 class 的 constructor 的 member initialization list 中调用该 class 的一个虚函数,安全吗?就实际而言,将该函数运行于其 class's data member 的初始化行动中,总是安全的。这是因为,正好我们看见, vptr 保证能够在 member initialization list 被扩展之前, 由编译器正确设定好。 但是在语意上这可能是不安全的,因为函数本身可能还得依赖未被设立值的 members。所以我并不推荐这种做法。然而,从 vptr 的整体角度来看,这是安全的。
何时需要供应参数给一个 base class constructor?(当我们给基类传递参数时会怎么样呢?(是指在给基类传递参数时调用了虚函数,而原文翻译欠妥。)) 这种情况下在 “ class 的 constructor 的 member initialization list 中” 调用该 class 的虚拟函数, 仍然安全吗? 不! 此时 vptr 若不是尚未被设定好, 就是被设定指向错误的 class。更进一步地,该函数所存取的任何 class's data members 一定还没有被初始化。
- 《Inside the C++ object Model》 Chapter7:
这次不是翻译错了,而是原版的书写错误,但是翻译版本也没有指出。
template < class type > class ScopeRules { public: void invariant() { _member = foo( _val ); } type type_dependent() { return foo( _member ); } // ... private: int _val; type _member; };
This is because_valis an invariant template class member of typeint; that is, the actual type usedto instantiate the template has no effect on the type of _val. Moreover, function resolution isdetermined by the signature of the function only and not its return type. Thus the type of_member(_val,这里是指代的_val而非_member)does not influence the choice of which foo()to invoke, and the invocation offoo()is notdependent on the template argument. The invocation must be resolved from the scope of thetemplate declaration. Within that scope is only the one candidate instance of foo()from which tochoose. (Note that this behavior cannot be reproduced with a simple macro expansion, such as ause of#definemacros of the preprocessor.)