Constructor / destructor / assignment operator (II)

Constructor / destructor / assignment operator

Constructors,Destructors,and Assignment Operators

9. not call virtual functions in the constructor and destructor process

Call Virtual Functions During Construction Never or Destruction.
Base class component in the derived class objects configured to derived class itself properly before the components are configured.

If the base class virtual function comprising, during configuration component base class, derived class components not yet initialized. If the virtual function call during class down to the derived class, the derived class function almost inevitable access to local variables, those variables that have not been initialized. This is a direct ticket to undefined behavior and debugging of the General Assembly of the night.

Treat this scenario, the safest approach believe that the object is in front of derived class constructor does not begin to be derived class.

Can not use the virtual function call down from the base class, during construction, I could "lead derived class will construct the necessary information is passed up to the base class constructor" be replaced with the make up.

#include<iostream>
class Transaction {
public:
	explicit Transaction(const std::string& logInfo);
	void logTransaction(const std::string& logInfo) const;//non-virtual

};
Transaction::Transaction(const std::string& logInfo)
{
	logTransaction(logInfo);//non-virtual调用
}
class BuyTransaction :public Transaction {
public:
	BuyTransaction(/*parameters*/)
		:Transaction(createLogString(/*parameters*/)) //将log信息传递给base class
	{}
private:
	static std::string createLogString(/*parameters*/);//static函数先于对象存在
};
  • During the construction and destruction do not call virtual functions, such as call will never drop to derived class (currently executed function than construction and destruction of that layer).

Operator = 10. The so returns a reference to * this

Have assignment operators return to * this.
This is a protocol, not mandatory. The advantage is to facilitate the continuous assignment. It applies to all assignment-related operations.

#include<iostream>
class Ration {
public:
	Ration(int val_=0)
		:val(val_)
	{
	}

	Ration& operator=(const Ration& rhs)
	{
		this->val = rhs.val;
		return *this;//这个协议实用于+=、-=、*=等
	}
private:
	int val;
};
int main()
{
	Ration r1(15);
	Ration r2, r3;
	r2 = r3 = r1;//赋值采用右结合律,等同于r2 = (r3 = r1)
}

11. The process of "self assignment" in the operator =

Handle assignment to self in operator =.
May be self-assigned scenes

a[i]=a[j];
*px=*py;

These obvious self-assignment, are the result of "Alias" will bring the so-called "Alias" is "there is more than one way to refer to an object," such as pointers and references, as well as to the succession of slices behavior brings results .

class Base {};
class Derived :public Base {};
void do_some_thing(Base& b, Derived* d);//此时b和d可能指向同一个对象

" Certificate with the test ."

class Bitmap{};
class Widget {
private:
	Bitmap* pb;
public:
	Widget& operator=(const Widget& rhs)
	{
		if (&rhs == this)return *this;//证同测试

		delete pb;
		pb = new Bitmap(*rhs.pb);
		return *this;
	}
};

To solve the above conventional method is still not solve the problems of abnormalities. If an exception is thrown in the assignment process, then point to Bitmap object will be deleted, such pointer is very harmful.

class Bitmap{};
class Widget {
private:
	Bitmap* pb;
public:
	Widget& operator=(const Widget& rhs)
	{
		Bitmap* pOrig = pb;
		pb = new Bitmap(*rhs.pb);
		delete pOrig;
		return *this;
	}
};

If the "self assignment" great probability, then, ideally with a "certificate with the test" in order to improve efficiency, so that you can solve the problem otherwise.
CAS , Copy and swap

class Bitmap{};
class Widget {
private:
	void swap(Widget&rhs)//交换两个Widget的pb指向
	{
	}
	Bitmap* pb;
public:
	Widget& operator=(Widget rhs)
	{
		swap(rhs);
		return *this;
	}
};
  • When the object is to ensure that when self-assignment operator = good behavior. Which techniques include more "source object" and "target audience" address, careful and thoughtful sentence order, and copy-and-swap.
  • When any function to determine if the operation is more than one object, wherein the plurality of objects are the same object, their behavior is still correct.

12. Each component forget which copying objects

Copy all part of an object
heavy responsibility to ensure that in addition to copy all of the local member variable. Whenever you take on the "Compose copying function derived class" must be very careful the first copy of its base class ingredients. Those ingredients tend to be private, so you can not directly access them, you should let the derived class calls the base class function of copying function.

In fact, two copying functions tend to have the same implementation body, which may tempt you to make a function to another function encouraged to avoid code duplication. Such attitude of excellence is commendable, but to make a copying function calls a copying function but can not so that you achieve the goals you want.

Make copy assignment operator call the copy constructor is unreasonable, because it's like trying to construct an object that already exists on this very up very fluent simply accept this suggestion: You should not make the copy assignment operator call the copy Constructor.

Make copy constructor calls the copy assignment operator is also pointless. Constructor is used to initialize a new object, but only came into force on assignent operator who has been the object is initialized. Correspondence has not been assigned the constructed objects, as in a uninitialized objects who do "only makes sense to initialize the object has" the same thing. the same boring.

If you find that your copy constructor and copy assignment operator have similar code, eliminate the practice of code duplication is to create a new member function to call such a function of both private and often tend to be named init. You can try such.

  • Copying function should ensure that the copy "all member variables within the object" and "base class for all components."
  • Do not try to achieve a copying function other copying functions. Their common function should be placed in the third function, copying function jointly by the two calls.
Published 139 original articles · won praise 55 · views 60000 +

Guess you like

Origin blog.csdn.net/Vickers_xiaowei/article/details/103754806