简体   繁体   English

带有继承的C ++运算符重载

[英]C++ operator overloading with inheritance

Let's say I have a class called Vehicle and another called Car that extends Vehicle class. 假设我有一个名为Vehicle的类,另一个名为Car类扩展了Vehicle类。 I want to implement ++ operators for both classes. 我想为两个类都实现++运算符。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <sstream>
#include <typeinfo>

#define debug(args...) // Just strip off all debug tokens
using namespace std;
// CUT begin
#define debug(args...) {dbg,args;cout<<endl;}
struct debugger{template<typename T> debugger& operator ,(const T& v){cout<<v<<" ";return *this;}}dbg;
template <typename T1,typename T2> inline ostream& operator<<(ostream& os,const pair<T1,T2>& p){return os<<"("<<p.first<<", "<<p.second<<")";}
template<typename T>inline ostream&operator<<(ostream& os,const vector<T>& v){string delim="[";for(unsigned int i=0;i < v.size();i++){os<<delim<<v[i];delim=", ";}return os<<"]";}
template<typename T>inline ostream&operator<<(ostream& os,const set<T>& v){string delim="[";for (typename set<T>::const_iterator ii=v.begin();ii!=v.end();++ii){os<<delim<<*ii;delim=", ";}return os<<"]";}
template<typename T1,typename T2>inline ostream&operator<<(ostream& os,const map<T1,T2>& v){string delim="[";for (typename map<T1,T2>::const_iterator ii=v.begin();ii!=v.end();++ii){os<<delim<<*ii;delim=", ";}return os<<"]";}
// CUT end


class Vehicle
{
public:
    int n;
    Vehicle(int n):n(n){cout<<"Ctor Vehicle "<<n<<endl;}
    Vehicle(Vehicle& v):n(v.n){cout<<"Copy Ctor Vehicle "<<n<<endl;}
    virtual ~Vehicle(){cout<<"Dtor Vehicle "<<n<<endl;}
    virtual ostream& dump(ostream& os){return os<<"Vehicle("<<n<<")";}
    string to_str(){stringstream s; dump(s); return s.str();}
    virtual Vehicle& operator++(){n++;return *this;}
    virtual Vehicle operator++(int x){Vehicle v(*this); operator++(); return v;}
};

class Car: public Vehicle
{
public:
    Car(int n): Vehicle(n){cout<<"Ctor Car "<<n<<endl;}
    virtual ~Car(){cout<<"Dtor Car "<<n<<endl;}
    virtual ostream& dump(ostream& os){return os<<"Car("<<n<<")";}
    virtual Car operator++(int x){Car v(*this); operator++(); return v;}
    /* data */
};
ostream& operator<<(ostream& os,  Vehicle& v)
{
    return v.dump(os);
}

int main(int argc, char const *argv[])
{
    Vehicle * v = new Car(10);
    // cout<<c++<<endl;
    // cout<<c<<endl;
    return 0;
}

I get the following error with gcc: 我收到gcc的以下错误:

C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:16:0: warning: "debug" redefined [enabled by default]
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:13:0: note: this is the location of the previous definition
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:44:14: error: invalid covariant return type for 'virtual Car Car::operator++(int)'
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:35:18: error:   overriding 'virtual Vehicle Vehicle::operator++(int)'
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp: In member function 'virtual Car Car::operator++(int)':
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:44:57: error: no matching function for call to 'Car::operator++()'
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:44:57: note: candidate is:
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:44:14: note: virtual Car Car::operator++(int)
C:\Users\Rajat\Documents\GitHub\interview-preparation\cpp_test.cpp:44:14: note:   candidate expects 1 argument, 0 provided

How do I get ++ operators for both Car and Vehicle with minimum number of virtual overrides? 如何以最少的虚拟覆盖数获得CarVehicle ++运算符?

Change 更改

virtual Car operator++(int x){Car v(*this); operator++(); return v;}

to

virtual Vehicle operator++(int x){Car v(*this); Vehicle::operator++(); return v;}
  1. While overriding operator++, return type should not be changed. 在覆盖operator ++时,不应更改返回类型。
  2. Explicitly mention that you want to call parent class's operator++ Vehicle::operator++() 明确提到您要调用父类的operator ++ Vehicle::operator++()

With that change, your program produces this output 更改后,您的程序将产生此输出

Ctor Vehicle 10
Ctor Car 10

Another way to do that is through CRTP and operator overloading helpers (Like boost operators header ) 另一种方法是通过CRTP和运算符重载助手(如boost操作符header

Suposse you have the following helper: 假设您有以下帮手:

template<typename T>
struct AddHelper
{
    T& operator++()
    {
        T& reference = static_cast<T&>(*this);
        reference.add();
        return reference;
    }

    T operator++(int)
    {
        AddHelper<T> copy( *this );
        operator++();
        return static_cast<T>(copy);
    }
};

The add() implementation is provided by the base class: add()实现由基类提供:

class Vehicle
{
private:
    int _n;
public:
    void add(int n) { _n += n; }

    ...
};

Because Vehicle::add() is public, we can use it in every Vehicle subclasses, thats means you can have specific operator++ for every Vehicle subclasses thanks to AddHelper: 由于Vehicle::add()是公共的,因此我们可以在每个Vehicle子类中使用它,这意味着借助AddHelper,您可以为每个Vehicle子类具有特定的operator ++

class Car : public Vehicle , public AddHelper<Car>
{
    Car(int n) : Vehicle(n) {}
    ...
};

class Motorcicle : public Vehicle , public AddHelper<Motorcicle>
{
    Motorcicle(int n) : Vehicle(n) {}
    ...
};

class Bus : public Vehicle , public AddHelper<Bus>
{
    Bus(int n) : Vehicle(n) {}
    ...
};

... //Ad infinitum

Another advantage of this way is that it doesnt use virtual functions to provide the polymorphism, so its more efficient (Static polymorphism instead of dynamic polymorphism). 这种方式的另一个优点是它不使用虚拟函数来提供多态性,因此其效率更高(静态多态性代替动态多态性)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM