唯有当这些函数被调用,他们才会被编译器创建出来。
请记住:
编译器可以暗自为class创建default构造函数、copy构造函数、copy assignment操作符,以及析构函数。
请记住:
为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明为private并且不予实现。使用像Uncopyable这样的base class也是一种做法。
析构函数的运作方式是:最深层派生的那个class其析构函数最先被调用,然后是其为每一个base class的析构函数被调用。
请记住:
请记住:
请记住:
解释:
在C++中,当你在构造函数或析构函数中调用一个虚函数时,它不会执行你期待的"多态"行为,即它不会调用任何派生类的覆盖版本。这是因为,当构造函数或析构函数执行时,对象的类型被视为正在构造或析构的类的类型,而不是任何派生类的类型。
让我们通过一个例子来说明这个问题:
#include
using namespace std;
class Base {
public:
virtual void foo() { cout << "Base::foo\n"; }
Base() { foo(); }
virtual ~Base() { foo(); }
};
class Derived : public Base {
public:
void foo() override { cout << "Derived::foo\n"; }
Derived() { foo(); }
~Derived() { foo(); }
};
int main() {
Derived d; // 输出?
return 0;
}
你会看到程序的输出为:
Base::foo
Derived::foo
Derived::foo
Base::foo
即使 foo 在 Derived 中被覆盖,在 Base 的构造函数和析构函数中调用 foo 仍会调用 Base 的版本,而不是 Derived 的版本。这通常不是你期望的行为,因此最好的做法就是避免在构造函数和析构函数中调用虚函数,除非你确切知道你在做什么,且你的设计确实需要这样做。
请记住:
请记住:
请记住: