#cpp #классы #конструктор #преобразование_типов
Есть два класса: A и B. Если производится копирование обьектов одного и того же класса, то вызывается конструктор копирования и копирует соответствующие поля. А вот если произвести такое: A a; B b; a = (A)b; Как работает копирование в этом случае?
Ответы
Ответ 1
Если в классе B имеется доступный оператор преобразования типов из типа класса B в тип класса A, то он вызывается в выражении приведения типа (A)b, результатом которого является временный объект типа A. Этот временный объект присваивается объекту a с помощью копирующего или перемещающего оператора присваивания в предложении a = (A)b; Вот демонстрационная программа #includestruct 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.
Комментариев нет:
Отправить комментарий