为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次



我正在Visual Studio 2017中运行。我的程序定义了一个带有转换运算符的类,并定义了等效的转换函数。

#include <iostream>
#include <string>
template<class T, class U>
struct A
{
A();
~A() { std::cout << "In A destructorn"; delete n; }
A(T i);
A(const A& a);
operator A<U,T>();
T* n;
};
template<class T, class U>
A<T,U>::A()
{
n = new T;
*n = 0;
}
template<class T, class U>
A<T,U>::A(T i)
{
n = new T;
*n = i;
}
template<class T, class U>
A<T,U>::A(const A& a)
{
std::cout << "In A copy constructorn";
n = new T;
*n = *(a.n);
}
template<class T, class U>
A<T,U>::operator A<U,T>()
{
A<U,T> aut;
*(aut.n) = static_cast<U>(*n);
return aut;
}
template<class T, class U>
std::ostream& operator<<(std::ostream& os, A<T,U>& a)
{
os << *(a.n);
return os;
}
template<class T, class U>
A<U,T> convert(A<T,U>& a)
{
A<U,T> c;
*(c.n) = static_cast<U>(*(a.n));
return c;
}
int main()
{
std::string s;
A<int, unsigned int> a1(-1);
std::cout << a1 << "n";
A<unsigned int, int> a2 = A<unsigned int, int>(a1);
std::cout << a2 << "n";
A<unsigned int, int> a3 = convert(a1);
std::cout << a3 << "n";
std::cout << "Press ENTER to exitn";
getline(std::cin, s);
}

当我在没有优化的情况下编译时,输出是

-1
In A copy constructor
In A destructor
In A copy constructor
In A destructor
4294967295
In A copy constructor
In A destructor
4294967295
Press ENTER to exit

复制构造函数在程序调用转换运算符后被调用两次,但在调用执行相同操作的函数convert()后仅被调用一次。在对转换运算符的调用中,程序似乎正在创建一个临时对象,而函数convert()不会导致该对象生成。为什么程序在调用转换运算符之后调用复制构造函数的次数与程序在调用convert()之后调用复制构造器的次数之间存在差异?

的定义

A<unsigned int, int> a2 = A<unsigned int, int>(a1);

真的是

A<unsigned int, int> a2 = A<unsigned int, int>(a1.operator A<unsigned int, int>());

相当于

A<unsigned int, int> temporary_compiler_generated_object = a1.operator A<unsigned int, int>();
A<unsigned int, int> a2 = temporary_compiler_generated_object;

这里需要调用临时对象的复制构造函数以及a2

最新更新