C ++运算符为2个独立的类成员重载类对象

问题描述 投票:-2回答:3

让我们说我上课了

class Car
{
public:
...
friend operator<(const Car&car1, const Car&car2){
   return car1.getYear() < car2.getYear()
}
private:
   int year;
   double price;
   string brand;
};

如果我想根据价格比较汽车,如何重载同一​​个操作员?我必须创建两个Car对象,并且我想要使用年份来比较第一个汽车对象,我想要使用它的价格来比较第二个汽车对象。

谢谢!

c++ class operator-overloading
3个回答
0
投票

如果你的类有一个价格的getter,那么你不需要编写一个重载的运算符。你可以简单地说:

  Car c1, c2;
  // stuff
  if ( c1.Price() < c2.Price() ) {
       // do something
  }

同样,您可能不需要在原始帖子中写入重载;你可以用一个吸气剂。注意我并不是说吸气剂是好主意。


0
投票

如果我想根据价格比较汽车,如何重载同一​​个操作员?

避免这种方法会更好。相反,使用两个不同的仿函数类。让调用代码选择他们想要使用的仿函数。

struct CompareByYear
{
   bool operator()(Car const& car1, Car const& car2)
   {
      return (car1.getYear() < car2.getYear());
   }
};

struct CompareByPrice
{
   bool operator()(Car const& car1, Car const& car2)
   {
      return (car1.getPrice() < car2.getPrice());
   }
};

0
投票

这种方法起初可能看起来很奇怪,但是如果有多种方法来比较类的内部数据类型成员,则可以非常简单地遵循和实现。

class Car {
public:
    enum Comparetor {
        BY_YEAR = 0,
        BY_PRICE = 1,
    };

private:    
    int   _year;
    float _price;
    std::string _make;

public:
    Car() :
        _year( 0 ),
        _price( 0 ),
        _make( "" ) 
    {}
    Car( int year, float price, const std::string& make ) :
        _year( year ),
        _price( price ),
        _make( make ) 
    {}

    int yearOf() const {
        return _year;
    }

    float priceOf() const {
        return _price;
    }

    std::string makeOf() const {
        return _make;
    }

    bool compareByLT( Car::Comparetor comp, Car& car2 ) {
        switch ( comp ) {
            case BY_YEAR: {
                return _year < car2._year;
                break;
            }
            case BY_PRICE: {
                return _price < car2._price;
                break;
            }
        }
    }
};   

int main() {    
    Car car1( 2017, 24785.0f, "Ford Mustang" );
    Car car2( 2018, 21579.0f, "Hyundai Elantra" );

    if ( car1.compareByLT( Car::BY_YEAR, car2 ) ) {
        std::cout << car1.makeOf() << " is older than " << car2.makeOf()
            << " by " << car2.yearOf() - car1.yearOf() << " year" << std::endl;
    } else {
        std::cout << car2.makeOf() << " is older than " << car1.makeOf()
            << " by " << car1.yearOf() - car1.yearOf() << " year" << std::endl;
    }

    if ( car1.compareByLT( Car::BY_PRICE, car2 ) ) {
        std::cout << car1.makeOf() << " is cheaper than " << car2.makeOf()
            << " by $" << car2.priceOf() - car1.priceOf() << std::endl;
    } else {
        std::cout << car2.makeOf() << " is cheaper than " << car1.makeOf()
            << " by $" << car1.priceOf() - car2.priceOf() << std::endl;
    }

    _getch(); // #include <conio.h> prevent debugging console on Windows in Visual Studio from closing.
    return 0;
}

由于含糊不清,您尝试执行的方法不起作用。意味着如果您尝试定义2个不同的运算符,使用相同的2个相同对象意味着它们的声明/定义/签名完全相同,编译器如何解析使用哪个overload。它不知道如何区分你的意思。我应该通过priceyear进行比较......?并且操作员不能接受另一个参数来知道哪一个。

如果由于某种原因,您需要的代码库要求您必须定义运算符,因为某种继承或数据结构机制......然后您可以仅为其中一个值(成员类型)重载运算符。你必须选择最有意义的使用哪一个。然后,对于其他数据,您必须编写函数或方法来执行此操作。我在这里简单地展示的是,您可以将类的内部数据的所有比较总结为单个函数,调用者必须通过该函数来传递要比较的枚举类型。

或正如其他人所说;如果你有访问方法来检索私有成员,那么如果它们是以类型构建的,或者是已经为它们定义了运算符的类型,那么你可以简单地进行比较。

对上面当前类的跟进:好的,所以我们现在有一个比较函数,比较小于,我们现在想要做大于的相同。正如我们之前所做的那样,完全不完全写出大于版本,你可以像这样简化第二种方法:

 bool compareByGT( Car::Comparetor comp, Car& car2 ) {
     return !( compareByLT( comp, car2 ) );
 }

这节省了大量不必要的代码输入,最大限度地减少了错误;但是你的第一个功能必须100%无错误才能使第二个功能准确可靠。


现在,如果您尝试这样做:为类本身定义operator<()并在类之外定义友元版本,如下所示:

{
    // Internal: Belongs to class
    bool operator<( const Car& other ) {
        _year < other._year;
    }

    // Friend of this class
    friend bool operator<( const Car& car1, const Car& car2 );
};

bool operator<( const Car& car1, const Car2& car2 ) {
    return car1._price < car2.price;
}

你认为会发生什么?

当你使用compare运算符时,这很简单:

if ( car1 < car2 ) {
    // Do something...
} else { 
    // Do something else...
}

它将决定使用属于该类的那个。

现在,如果你注释掉属于类的那个保持代码中其他地方的if语句,那么代码就不会中断,当你编译,构建并通过调试器再次运行它时它应该没有问题地执行时间它将由朋友版本进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.