Есть два класса: A и B.
Если производится копирование обьектов одного и того же класса, то вызывается конструктор копирования и копирует соответствующие поля. А вот если произвести такое:
A a;
B b;
a = (A)b;
Как работает копирование в этом случае?
Ответ
Если в классе B имеется доступный оператор преобразования типов из типа класса B в тип класса A, то он вызывается в выражении приведения типа (A)b, результатом которого является временный объект типа A. Этот временный объект присваивается объекту a с помощью копирующего или перемещающего оператора присваивания в предложении
a = (A)b;
Вот демонстрационная программа
#include
struct A
{
A & operator =( const A & )
{
std::cout << "A::operator =" << std::endl;
return *this;
}
};
struct B
{
operator A() const
{
std::cout << "operator B::A()" << std::endl;
return A();
}
};
int main()
{
A a;
B b;
a = ( A )b;
return 0;
}
Ее вывод на консоль
operator B::A()
A::operator =
Оператор преобразования может быть объявлен также со спецификатором функции explicit. Например,
explicit operator A() const;
Или более "запутанный" пример преобразований, когда оператор преобразования перегружен для lvalue и rvalue
#include
struct A
{
A()
{
std::cout << "A::A()" << std::endl;
}
A( const A & )
{
std::cout << "A::A( const A & )" << std::endl;
}
A & operator =( const A & )
{
std::cout << "A::operator =( const A & )" << std::endl;
return *this;
}
A & operator =( A && )
{
std::cout << "A::operator =( A && )" << std::endl;
return *this;
}
};
struct B
{
explicit operator A() const &
{
std::cout << "operator A() &" << std::endl;
return A();
}
explicit operator A() const &&
{
std::cout << "operator A() &&" << std::endl;
return A();
}
};
int main()
{
A a;
B b;
a = ( A )b;
std::cout << std::endl;
a = ( A )B();
return 0;
}
Вывод этой программы на консоль
A::A()
operator A() &
A::A()
A::operator =( A && )
operator A() &&
A::A()
A::operator =( A && )
Например, для предложения
a = ( A )B();
вызывается оператор преобразования для rvalue временного объекта, созданного вызовом B()
operator A() &&
Затем внутри этого оператора создается временный объект типа A
A::A()
Этот временный объект с помощью перемещающего оператора присваивания присваивается объекту a
A::operator =( A && )
Самый простой вариант - это когда в классе A имеется конструктор преобразования. Например,
#include
struct A
{
A() {}
explicit A( const struct B & );
A & operator =( const A & )
{
std::cout << "A::operator =( const A & )" << std::endl;
return *this;
}
};
struct B
{
};
A::A( const B & )
{
std::cout << "A::A( const B & )" << std::endl;
}
int main()
{
A a;
B b;
a = ( A )b;
return 0;
}
Вывод программы на консоль
A::A( const B & )
A::operator =( const A & )
В определении класса A объявлен преобразующий конструктор
explicit A( const struct B & );
который вызывается при приведении типов в выражении ( A )b
И, наконец, если класс B является производным от класса A, то вы можете просто записать
a = b;
В этом случае объект класса B неявно преобразуется в объект класса A и вызывается копирующий оператор присваивания класса A
Комментариев нет:
Отправить комментарий