赋值运算符和类型转换函数之间的区别,用于将用户定义的用户转换为另一个

时间:2014-12-12 12:26:45

标签: inheritance c++11 constructor

#include <iostream>
using namespace std;

// Assignment operator: allow implicit conversion from a particular type on assignments.
// Type-cast operator: allow implicit conversion to a particular type.

class car;

class bus
{

public:bus & operator = (car & b)
                                // implicit conversion by assignment operator
  {
    cout << endl << "Assignment operator of BUS " << endl;
    return *this;
  }

/*  operator  car () const      //    Type-cast operator
  {
    return (car ());            // error: invalid use of incomplete type ‘class car’
  }*/
};
class car
{
public:
  car ()
  {
  }
  car (const bus & b1)
  {
    cout << endl << "conversion constructor";
  }
  car & operator = (bus & b)    // implicit conversion by assignment operator
  {
    cout << endl << "Assignment operator of car " << endl;
    return *this;
  }
operator   bus () const       //    Type-cast operator
  {
    cout << endl << "Typecast operator-in car" << endl;
    return (bus ());
  }
};

int
main ()
{
  bus b;
  car c1 = b;                   // call convertion constructor of car object

  c1 = b;                       // call assignment operator of car
  // or 
  b = c1;                       // call assignment operator of bus

  car c2; 
  bus b2 = bus (c2);            //call   Type-cast operator of car`enter code here`

  // we cannot define  Type-cast operator in bus 
  // eventhough forward decleration is done 
  // error: invalid use of incomplete type ‘class car’
  // so car c=car(b)  is not possible

我的问题是从用户定义类型到另一种类型的隐式转换        1)如果在两者中声明的赋值操作符可以用于bus = car和car = bus的用途           那为什么使用类型转换运算符的复杂语法?有什么不同吗           如果是这样 ?        2)上面提到的复制构造函数和转换构造函数之间是否存在任何关系,我注意到的一个相似性是在赋值时调用,而参数传递的copyconstructor和convertion构造函数是不同的。还有其他差异或相似之处。        3)尽管前向去除已经完成但是有一个错误:&#34;无效使用不完整类型的“汽车”&#34;该代码被评论,为什么?

提前致谢

1 个答案:

答案 0 :(得分:0)

正如Joachim Pileborg在comments中提到的,您可以使用CRTP来完成您的需要:

// code could stand for more tidying, but you get the idea
#include <iostream>
#include <typeinfo>
using namespace std;

// Assignment operator: allow implicit conversion from a particular type on assignments.
// Type-cast operator: allow implicit conversion to a particular type.

template <typename T>
class Car
{
public:
  Car () = default;
  Car (const T & b1)
  {
    cout << endl << "conversion constructor to " << typeid(T).name();
  }
  Car & operator = (T & b)    // implicit conversion by assignment operator
  {
    cout << endl << "Assignment operator of car to " << typeid(T).name() << endl;
    return *this;
  }

  T type() const
  {
    cout << endl << "Typecast operator-in car to " << typeid(T).name() << endl;

    return T();
  }
};

class Bus : public Car<Bus>
{

public:
   Bus() = default;
   Bus(Car<Bus>& b)
   {
      *this = b;
   }

   Bus & operator = (Car<Bus> & b)  // implicit conversion by assignment operator
   {
      cout << endl << "Assignment operator of BUS " << endl;
      return *this;
   }

   Car  car () const      //  Type-cast operator
   {
      return Car<Bus>::type();
   }
};


int main ()
{
   Bus b;
   Car<Bus> c1 = b;                   // call convertion constructor of car object

   c1 = b;                       // call assignment operator of car
   // or 
   b = c1;                       // call assignment operator of bus

   Car<Bus> c2; 
   Bus b2 = Bus (c2);            //call   Type-cast operator of car
   return 0;
}

CRTP,或者奇怪的重复模板模式,允许我们使用模板,以便基类可以知道派生类。

在这种情况下,我们将Car设为模板化类,Bus来自Car<Bus>,允许我们在Car类中执行转换为{{ 1}}。

Live Example


回答你的问题:

  1. 如果两者中声明的赋值运算符可以用于bus = car和car = bus的目的那么为什么使用Type-cast运算符的复杂语法?
  2. 此处的问题是,Bus需要了解CarBus的完整实施需要了解Bus的完整实施情况。请参阅此处的循环参考?模板化,前向声明和使用指针使我们能够解决这个问题。

    1. 复制构造函数和提到的转换构造函数之间是否存在任何关系
    2. 我不确定你在这里问的是什么,但我会采取刺。接受另一种类型的构造函数可以被视为复制构造函数&#39;这是执行转换,但这可能是您对转换构造函数的意思。

      1. 即使完成了前方声明,也会出现错误:&#34;无效使用不完整类型的“汽车”&#34;为什么?
      2. 这将我们带回#1和循环引用。如果你转发声明,你可以使用指针绕过它。