函数调用的重载操作符

Overloading operator for a function call

本文关键字:操作符 重载 函数调用      更新时间:2023-10-16

是否可以仅为一个函数重载操作符?我想覆盖'->'操作符,但只有当它被调用与打印函数(->打印())。我知道这是一个奇怪的请求,但我正在努力实现一个特定的API,我需要这样的东西。

例如:

Cat cat;
cat.walk();
cat->print(); //I want to overload only this call

但是,我不想在所有情况下重载'->'操作符。例如:

Cat* cat;
cat->walk(); //this should work normally
cat->print(); //this wouldn't call the print() function, 
              //since I overloaded cat->print()

可以用一个虚拟返回对象重载->操作符。true print()方法可以设置为私有,并且只能通过访问器访问。在一个最小的例子中:

#include <iostream>
struct Cat;
struct CatAccessor {
private:
    friend class Cat;
    CatAccessor(Cat& cat) : cat(cat) {}
    Cat& cat;
public:
    void print();
    CatAccessor* operator->() { return this; }
};
struct Cat {
    CatAccessor* operator->() { return CatAccessor(*this); }
    void walk() { std::cerr << "Walk called" << std::endl; }
private:
    void print() { std::cerr << "Print called" << std::endl; }
    friend class CatAccessor;
};
void CatAccessor::print() { cat.print(); }
int main() {
    Cat cat;
    cat.walk();
    cat->print();
    Cat* catp = &cat;
    catp->walk();
    // error: catp->print();
    return 0;
}

如果您可以将print()移动到基类,则非常容易:

class CatBase
{
public:
    void print();
};
class Cat : private CatBase
{
public:
    void walk();
    CatBase* operator->() { return this; }
    const CatBase* operator->() const { return this; }
};

C++不允许您"直接"做这样的事情。最好的方法是从Cat类继承,使方法print为virtual,并在子类中以不同的方式实现它。