2014-09-07 2 views
0

Я хочу спросить, что на самом деле означает преобразование объектов, например: Почему я не могу получить доступ к печати в классе B, используя foo после присвоения ему A?!Что происходит для конструкторов, которые принимают объекты в качестве параметров?

#include <iostream> 
using namespace std; 

class A {}; 

class B { 
public: 
// conversion from A (constructor): 
B (const A& x) {} 
void print(){cout << "Huo Jackman!\n";} 


}; 
int main() 
{ 
    A foo; 
B bar = foo; // calls constructor 
foo.print(); 


return 0; 
} 

ответ

3

Использование:

bar.print(); 

Пожалуйста, обратите внимание, что первоначальный foo объект не изменяется, когда bar создается. foo имеет тип class A, который не содержит метода print, а на C++ нельзя добавлять методы «на лету».

+0

то, что произошло при создании объекта бар и переданный объект foo t o это? o.O –

+0

@OmarKhaled ничего, ваш конструктор 'B (const A & x)' ничего не делает. –

+0

, так что я получаю, когда я передаю (const a% x) в качестве параметра конструктору класса B? –

0

Ваш код является примером преобразования типов. Делая следующее

B (const A& x) {} 

Вы строите новый объект типа B из объекта типа А. Здесь исходный объект А остается без изменений. Когда вы пишете

A foo; 
B bar = foo; // calls constructor 

Вы впервые создали Foo, который является объектом типа А. Из этого объекта вы сейчас создаете объект типа B принимает Foo в качестве аргумента. Он построит бар, но оставит foo без изменений. Вот почему вы не можете вызывать метод печати на foo, поскольку метод печати определен только для bar, а не для foo. Теперь, когда вы спросили, что вы получите, сделав это.

Рассмотрим следующий код

void fun (B& b) 
{ 
    // do something with object b 
} 

void main() 
{ 
    A a; 
    fun (a); 
} 

Функция удовольствия здесь ожидает объект типа B, но она передается объект типа А. Перед генерацией ошибка компиляции, компилятор попытается увидеть, если есть каким-либо образом он может построить объект типа B из объекта типа A. Если вы не определили какое-либо преобразование, компилятор будет генерировать ошибку компиляции. Но здесь, поскольку мы можем построить объект типа B, взяв A в качестве аргумента, компилятор сделает это, и вызов будет успешным. Этот тип механизма имеет некоторые непредвиденные последствия. Здесь вы хотели вызвать функцию fun с объектом типа B, но вызов преуспел даже с объектом типа A, поскольку компилятор выполняет неявное преобразование из типа A в тип B с помощью конструктора в B. Чтобы остановить такое поведение, явный "может быть использован для соответствующего конструктора.

explicit B (const A& x) {} 

Рассмотрим следующий код внутри класса B

B& operator= (const A& x) {return *this;} 

Это не создаст новый объект. Однако он будет использоваться для модификации объекта типа B с использованием объекта типа A. Если с другой стороны мы хотим построить объект типа A из объекта типа B, нам придется использовать оператор типа (функция преобразования) в классе B:

operator A() { return A(); } 

Так что класс B будет выглядеть примерно так:

class B 
{ 
    public: 
     B (const A& a) {} // conversion from A using constructor 
     B& operator= (const A& a) { return *this;} // conversion from A using assignment 
     operator A() { return A(); } // conversion to A using typecast operator 
}; 

int main (int argc, char** argv) 
{ 
    A a;   
    B b= a; // Construct B from A using constructor (1st one above) 
    b = a;  // copy a into b using assignment operator (2nd one above) 
    a = b;  // construct A from B using typecast operator (3rd one above) 
    return 0; 
} 

Пожалуйста, обратитесь к this и this для некоторой дополнительной информации

+0

Отличный ответ: спасибо, брату .understood :) @Vimal –

+0

это та же концепция для B & operator = (const A & x) {return * this;} // преобразование в A (оператор типа-литья)? –

+0

@ Omar Khaled Я отредактировал свое сообщение, чтобы ответить на ваш запрос и также включил некоторые релевантные ссылки. Надеюсь это поможет. – vchandra