[英]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? 如何以最少的虚拟覆盖数获得
Car
和Vehicle
++
运算符?
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;}
Vehicle::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.