(C++ Object Model): Program transformation semantics

Program transformation semantics

  • For the code we write, the compiler will split the code into code that is easier for the compiler to understand and implement.
  • Take a look at how the compiler parses these codes.
  • From the programmer's perspective/from the compiler's perspective  
  • The programmer's view of code and the compiler's view of code are constantly switching.

Initialize object when defined

class X
{
public:
	int m_i;
	X(const X& tmpx)
	{
		m_i = tmpx.m_i;
		cout << "拷贝构造函数被调用" << endl;
	}
	X()
	{
		m_i = 0;
		cout << "构造函数被调用" << endl;
	}
};

int main()
{
	
	X x0;
	x0.m_i = 15;
	X x1 = x0;        // 定义的时候初始化,调用拷贝构造函数
	X x2(x0);         // 定义的时候初始化,调用拷贝构造函数
	X x3 = (x0);      // 定义的时候初始化,调用拷贝构造函数
}
  • Output result:

  • Switch to the compiler perspective, the compiler will be split into two steps (compiler perspective)
    • X x3; Step 1: Define an object and allocate memory for the object. From the perspective of the compiler, this sentence does not call the constructor of the X class
    • x3.X::X(x0); Step 2: Call the copy constructor of the object directly
  • to sum up:
    • The compiler first creates the object, and then calls the object's copy constructor to copy

Initialization of parameters

class X
{
public:
	int m_i;
	X(const X& tmpx)
	{
		m_i = tmpx.m_i;
		cout << "拷贝构造函数被调用" << endl;
	}
	X()
	{
		m_i = 0;
		cout << "构造函数被调用" << endl;
	}
	~X()
	{
		cout << "析构函数被调用" << endl;
	}
};

void func(X tmpx)
{
	return;
}

int main()
{
	X x0;
	func(x0);
	return 1;
}
  • Output result

  • Programmer's point of view: When passing parameters, call the copy constructor to copy x0 to tmpx. After the function is executed, tmpx is destructed.
  • From a modern compiler perspective: the function first creates a tmpx object, and then calls the object's copy constructor to copy x0 to tmpx. Similar to the execution process of X tmpx(x0).

Old compiler perspective

  • X tmpobj; The compiler generates a temporary object
  • tmpobj.X::X(x0); call the copy constructor
void func(X tmpx)
{
	return;
}
老编译器看func(老编译器角度)
void func(X &tmpx)
{
	return;
}
  • func(tmpobj); call func with a temporary object
  • tmpobj.X::~X(); After func() is called, the destructor is called
  • Summary: The old compiler first constructs the temporary object outside, and then passes it to the function by reference (change the value passing method to reference).

Return value initialization

class X
{
public:
	int m_i;
	X(const X& tmpx)
	{
		m_i = tmpx.m_i;
		cout << "拷贝构造函数被调用" << endl;
	}
	X()
	{
		m_i = 0;
		cout << "构造函数被调用" << endl;
	}
	~X()
	{
		cout << "析构函数被调用" << endl;
	}
};

X func()
{
	X x0;
	//....
	return x0;   
}


int main()
{
	X my = func();
	return 1;
}
  • Output result (analysis from programmer's perspective):

  • The compiler's understanding of the above code (compiler perspective)
    • X my; just generates the object my, will not call the constructor of X
    • func(my); 
  • Func from the compiler perspective
void func(X &extra)
{
    X x0; //从编译器角度,这里不调用X的构造函数
    //...
    //...
    extra.X::X(x0);  //调用拷贝构造函数,将x0拷贝给外部传来的引用
    return;
}

Add a member function to the class

class X
{
public:
	int m_i;
	X(const X& tmpx)
	{
		m_i = tmpx.m_i;
		cout << "拷贝构造函数被调用" << endl;
	}
	X()
	{
		m_i = 0;
		cout << "构造函数被调用" << endl;
	}
	~X()
	{
		cout << "析构函数被调用" << endl;
	}
	void functest()
	{
		cout << "functest()被调用" << endl;
	}
};

X func()
{
	X x0;
	//....
	return x0;   
}


int main()
{
	func().functest();
	return 1;
}
  • Output result:

  • Programmer's perspective:
    • func (). functest ();
  • Compiler perspective
  • X my; will not call X's constructor
  • (func(my), my).functest(); Comma expression: first calculate expression 1, then expression 2, the result of the entire comma expression is the value of expression 2;
  • Where (func(my) is:
void func(X &extra)
{
    X x0; //从编译器角度,这里不调用X的构造函数
    //...
    //...
    extra.X::X(x0);  //调用拷贝构造函数,将x0拷贝给外部传来的引用
    return;
}

 

Guess you like

Origin blog.csdn.net/baidu_41388533/article/details/108670779