永发信息网

构造函数(析构函数)中调用虚函数

答案:2  悬赏:20  手机版
解决时间 2021-03-05 01:22
  • 提问者网友:無理詩人
  • 2021-03-04 15:17
构造函数(析构函数)中调用虚函数的例子??
调用结果是什么?
为什么?
谢谢~
最佳答案
  • 五星知识达人网友:狂恋
  • 2021-03-04 16:40
根据Effective C++ (3rd Edition) ---- Item 9:
Never call virtual functions during construction or destruction.
(不要在构造函数和析构函数中调用虚函数)
其中举例为:(英文)
class Transaction {
public:
Transaction();
virtual void LogTransaction() const = 0;
// ...
};

Transaction::Transaction()
{
// ...
LogTransaction();
}

class BuyTransaction : public Transaction {
public:
virtual void LogTransaction() const;
// ...
};
Consider what happen when this code is executed:
BuyTransaction b;
Clearly a BuyTransaction constructor will be called, but firt, a Transaction constructor must be called; base class parts of derived class objects are constructed before derived class parts are. The last line of the Transaction constructor calls the virtual function longTransaction, but this is where the surprise comes in. The version of logTransaction that't called is the one in Transaction, not the one in BuyTransaction -- even though the type of object being created is BuyTransaction. 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.
There's a good reason for this seemingly counterintuitive behavior. Because base class constructors execute before derived class constructors, derived class data members have not been initialized when base class constructors run. If virtual functions called during base class construction went down to derived classes, the derived class functions would almost certainly refer to local data members, but those data members would not yet have been initialized. That would be a non-stop ticket to undefined behavior and late-night debugging sessions. Calling down to parts of an object that have not yet been initialized is inherently dangerous. so C++ gives you no way to do it.

根据上面的原文看:调用的结果是(可能发生未定义行为)
这是由于(上例中)在BuyTransaction构造函数执行时,先执行基类(Transaction)的构造函数,而在Transaction的构造函数中又调用了(纯)虚函数logTransaction(),由于现在是在派生类里边定义函数,所以调用的logTransaction是BuyTransaction()里边的函数。这样有违背了你的初衷(调用Transaction里边的logTransaction())...
如果在虚函数里边有对派生类成员(不是从基类那里继承来的)的操作,那么更遭,以为在调用基类构造函数调时(派生类的成员还没有被初始化),这样就会导致未定义行为。
你最好看看原文的解释(英文部分)!
总之,记住不要在构造函数(析构函数)中调用虚函数!
全部回答
  • 1楼网友:山河有幸埋战骨
  • 2021-03-04 17:13
基类中的构造函数和析构函数调用虚函数总是会调用基类中的实现,它就跟普通函数一样了... 因为派生类构造在基类构造之后,派生类析构在基类析构之前...
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯