Item 9: Never call virtual functions during construction or destruction.
在构造和析构期间不要调用 virtual 函数,因为这类调用不会下降至 derived class (比起当前执行构造函数和析构函数的那层)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classTransaction { // base class for all public: // transactions Transaction(){ // base class ctor logTransaction(); // as final action, log this } virtualvoidlogTransaction()const= 0; // make type-dependent }; classBuyTransaction: public Transaction { // derived class public: virtualvoidlogTransaction()const; // how to log trans- }; ... BuyTransaction b;
b 在构造时,调用到父类Transaction的构造函数,其中对 logTransaction 的调用会被解析到 Transaction 类。 那是一个纯虚函数,因此程序会非正常退出。
在derived class 对象的 base class 构造期间,对象的类型是 base class 而不是 derived classo 不只 virtual 函数会被编译器解析至(resolve to) base class ,若使用运行期类型信息 RTTI(runtime type information, 例如 dynamic_casttypeid) ,也会把对象视为 base class 类型。
char greeting[] = "Hello"; char* p = greeting; //non-const pointer, non-const data constchar* p = greeting; //non-const pointer, const data char* const p = greeting; //const pointer, non-const data constchar* const p = greeting; //const pointer, const data
C++ 程序设计的惯例并非一成不变,而是取决于你使用 C++ 语言的哪一部分。例如, 在基于C语言的程序设计中,基本类型传参时传值比传引用更有效率。 然而当你接触 Object-Oriented C++ 时会发现,传常量指针是更好的选择。运用Template C++时尤其如此,因为彼时你甚至不知道所处理的对象的类型。 但是你如果又碰到了STL,其中的迭代器和函数对象都是基于C语言的指针而设计的, 这时又回到了原来的规则:传值比传引用更好。