Negative tive C ++ clause 9: virtual functions are never called in the analysis and constructor.

Source: Internet
Author: User

Each time you create a transaction object, you must create an appropriate record in the audit log. The following is a reasonable practice:

Class transaction
{
Public:
Transaction ()
{
Init ();
}
Virtual void logtransaction () const {STD: cout <"transaction ";};
Protected:

PRIVATE:
Void Init ()
{
Logtransaction ();
}
};

Class buytransaction: Public transaction
{
Public:
Buytransaction (): A (5 ){}
Virtual void logtransaction () const {STD: cout <"buytransaction" <;};
Protected:
PRIVATE:
Int;
};

Class selltransaction: Public transaction
{
Public:
Virtual void logtransaction () const;
Protected:
PRIVATE:
};

Inline void testitem9 ()
{
Buytransaction B;
}

During base class construction, the virtual function will never fall to the derived classes Class. Instead, the object is treated as a base object.

Informal statement: During base class construction, virtual functions are not virtual functions.

Because the base class constructor executes earlier than the derived class constructor, when the base class constructor executes, the member variables of the derived class have not been initialized. If the virtual function called during the period drops to the derived class, the derived class function will almost certainly use the local member variable, and those member variables are not initialized yet. This leads to unclear behavior and overnight debugging.

In fact, there is a more fundamental reason. During the base class construction of the derived object, the object type is base class rather than derived class. Not only does the virtual function be parsed to the base class by the compiler, but if runtime type information (such as dynamic_cast and typeid) is used, the object is also considered as the base class type. In this example, when the transaction constructor is executing and intends to initialize the "base class component in the buytransaction object", the object type is transaction. The "buytransaction exclusive component" in this object has not been initialized. Therefore, the safest way to deal with this is to check that they do not exist. The object will not become a derived class object before the derived class constructor starts execution.

The same principle applies to destructor. Once the derived class destructor starts execution, the derived class member variables in the object are displayed with undefined values,

Therefore, C ++ seems to be nonexistent. after entering the base class destructor, the object becomes a base class object.

How can we ensure that a proper version of logtransaction is called every time an object in the transaction inheritance system is created? Calling a virtual function in a constructor is incorrect.

Other solutions can solve this problem. One way is to change logtransaction to non-virtual in transaction, and then require the derived class to construct

The function passes necessary information to the transaction constructor. Then, the constructor can safely call non-virtual logtransaction. Like this:

Class transaction
{
Public:
Explicit transaction (const STD: string & loginfo );
Void logtransaction (const STD: string & loginfo) const;
Protected:

PRIVATE:
};
Transaction: transaction (const STD: string & loginfo)
{
Logtransaction (loginfo)
}

Class buytransaction: Public transaction
{
Public:
Buytransaction (parameters)
: Transaction (createlogstring (parameters ))
{
...;
}
Protected:
PRIVATE:
Static STD: String createlogstring (parameters );
Int;
};

In other words, because you cannot use the virtual function to call down from the base class, during the construction, you can replace derived class by "passing necessary constructor information to base class constructor.

In this example, use the Private Static function createlogstring in buytransaction. Yes, compared to giving base class in the member initialization list

Required data. It is easy to use helper functions to create a value and pass it to the base class constructor. If this function is static, it is impossible to accidentally point to "uninitialized member variables in the buytransaction object with immature initial values ".

Do not call virtual functions during constructor and destructor, because such calls never fall to the derived class (compared to the layer where the current constructor and destructor are executed ).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.