接受对象作为参数的构造函数发生了什么?

时间:2014-09-07 03:31:52

标签: c++

我想问对象转换的实际意义,例如: 为什么在将它分配给A后,我无法使用foo访问B类的打印?

#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;
}

2 个答案:

答案 0 :(得分:3)

使用:

bar.print();

请注意,创建foo时,原始bar对象不会更改。 foo的类型为class A,其中不包含print方法,而在C ++中,无法动态添加方法。

答案 1 :(得分:0)

您的代码是类型转换的示例。通过以下

B (const A& x) {}

您正在从类型A的对象构造类型B的新对象。这里原始对象A保持不变。当你写

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

您首先创建了foo,它是A类型的对象。从此对象开始,您将创建一个以Foo为参数的B类对象。它将构建柱,但将保持不变。这就是为什么你不能在foo上调用print方法的原因,因为print方法只是为bar而不是foo定义的。 现在,当你问到这样做会有什么好处。

考虑以下代码

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

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

这里的函数很有用,期望一个B类型的对象,但它正在传递一个A类对象。在生成编译错误之前,编译器会尝试查看是否有任何方法可以构造一个B类对象。类型A的对象。如果尚未定义任何转换,编译器将生成编译错误。但是在这里,因为我们可以构造一个以A作为参数的B类对象,编译器会这样做,并且调用将成功。这种机制确实会产生一些意想不到的后果。在这里,您希望使用类型B的对象调用函数fun,但是即使使用类型A的对象,调用也成功,因为编译器使用B中的构造函数执行从类型A到类型B的隐式转换。要停止此类行为,请关键字' explicit'可以在受影响的构造函数上使用。

explicit B (const A& x) {}

考虑B类中的以下代码

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

这不会创建任何新对象。但是,它将用于使用类型A的对象修改类型B的对象。另一方面,我们想要从类型B的对象构造类型A的对象,我们将不得不使用类型转换操作符(转换函数)在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;
}

有关其他信息,请参阅thisthis