为什么当转换函数仅一次调用复制构造函数两次时,转换运算符才会调用它两次?

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

#include <iostream>
#include <string>

template<class T,class U>
struct A
{
    A();
   ~A() { std::cout << "In A destructor\n"; 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,U>::A(T i)
{
    n = new T;
   *n = i;
}

template<class T,U>::A(const A& a)
{
    std::cout << "In A copy constructor\n";
    n = new T;
   *n = *(a.n);
}

template<class 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 exit\n";
    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()之后程序调用复制构造函数的次数之间有区别?

agercaigao 回答:为什么当转换函数仅一次调用复制构造函数两次时,转换运算符才会调用它两次?

定义

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

是真的

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

本文链接:https://www.f2er.com/3143925.html

大家都在问