构造函数,拷贝赋值函数的N种调用情况

一、 

class Date
{
public:
	Date()//构造函数
	{
		cout << "Date()" << endl;
	}
	Date(const Date& d)//拷贝构造
	{
		cout << "Date(const Date& d)" << endl;
	}
	Date& operator=(const Date& d)//赋值运算符重载
	{
		cout << "Date& operator=(const Date& d)" << endl;
		return *this;
	}
	~Date()//析构函数
	{
		cout << "~Date()" << endl;
	}
};

1.场景一

void fun1(Date d)
{}

int main()
{
	Date d1;
	fun1(d1);
	system("pause");
	return 0;
}
  • Date d1;调用构造函数
  • fun1(d1);d1值传递,要生成一个临时变量,拷贝构造(传值是拷贝构造
  • 俩次析构

2.场景二

void fun2(Date& d)
{}

int main()
{
	Date d1;
	fun2(d1);
	system("pause");
	return 0;
}
  • Date d1;调用构造函数
  • fun2(d1);传的是d1的引用,引用相当于别名,不创建临时变量,所以这里声明当不调用
  • 一次析构

3.场景三

Date fun3()
{
	Date d;
	return d;
}

int main()
{
	Date d2=fun3();
	system("pause");
	return 0;
}
  • 调用fun3(),Date d;调用一次构造函数
  • Date d2 = fun3();return d;返回一个临时变量,这时也要进行一次拷贝构造
  • Date d2 = fun3();调用一次拷贝构造
  • 编译器会自动优化,将上述俩次拷贝构造合并成一次(在同一表达式中)
  • 俩次析构

所以一共是,一次构造,一次拷贝构造,俩次析构

4.场景四:

Date& fun4()
{
	Date d;
	return d;
}

int main()
{
	Date d2=fun4();
	system("pause");
	return 0;
}
  • Date d;构造
  • Date d2=fun4();析构,fun4()形参一个匿名对象,匿名对象只在这行用以下,马上析构
  • 拷贝构造d2
  • 析构

5.场景五:

Date fun5()
{
	return Date();
}

int main()
{
	Date d3;
	d3 = fun5();
	system("pause");
	return 0;
}
  • Date d3:构造
  • fun5():函数内进行一次构造
  • d3 = fun5:赋值运算符重载
  • 俩次析构

6.场景六:

Date& fun6()
{
	return Date();
}

int main()
{
	Date d3;
	d3 = fun6();
	system("pause");
	return 0;
}

  • Date d3:构造
  • fun6():函数内进行一次构造
  • fun6()函数返回值是引用,构造了一个匿名参数,立马析构,调用一次析构
  • d3 = fun6():赋值运算符重载
  • 析构d3

二、

class AA
{
public:
	AA()//构造函数
	{
		cout << "AA()" << endl;
	}
	AA(const AA& d)//拷贝构造
	{
		cout << "AA(const AA& d)" << endl;
	}
	AA& operator=(const AA& d)//赋值运算符重载
	{
		cout << "AA& operator=(const AA& d)" << endl;
		return *this;
	}
	~AA()//析构函数
	{
		cout << "~AA()" << endl;
	}

};
AA f(AA a)
{
	return a;
}

1.场景一

void Test1()
{
	AA a1;
	a1 = f(a1);
}
  • AA a1:构造
  • f(a1):拷贝构造;传值:拷贝构造,传值过程不能优化
  • return a;返回一个临时变量拷贝构造
  • a出了作用域即被销毁,析构
  • a1 = f(a1)赋值运算符重载
  • 俩次析构

2.场景二:

void Test2()
{
	AA a1;
	AA a2 = f(a1);
}
  • AA a1:构造
  • f(a1):值传递,拷贝构造
  • AA  a2 = f(a1)拷贝构造,与函数AA的返回临时变量(return a)拷贝构造,俩次合并成一次,在用一个表单式中,编译器优化
  • 三次析构

3.场景三:

void Test3()
{
	AA a1;
	AA a2 = f(f(a1));
}
  •  AA a1:构造
  • f(a1):拷贝构造
  • f(f(a1)):拷贝构造 ;与f(a1)的返回值一起优化为一次
  • 一次析构
  • a2 = f(f(a1)):拷贝构造,与f(f(a1))的返回值一起优化为一次
  • 三次析构

猜你喜欢

转载自blog.csdn.net/audience_fzn/article/details/81451021