C++ 函数调用的重载运算符

C++ 函数调用的重载运算符,c++,operator-overloading,overloading,C++,Operator Overloading,Overloading,是否可以只为一个函数重载一个运算符。我想重写'->'运算符,但仅当使用打印函数->打印调用它时。我知道这是一个奇怪的请求,但我正在努力实现一个特定的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

是否可以只为一个函数重载一个运算符。我想重写'->'运算符,但仅当使用打印函数->打印调用它时。我知道这是一个奇怪的请求,但我正在努力实现一个特定的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()
但是,我不想在所有情况下都重载'->'运算符。例如:

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()
C++不允许您直接做这样的事情。最好的方法是继承类Cat,使方法print virtual并在子类中以不同的方式实现它

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

如果您可以将print移动到基类,则非常简单:

class CatBase
{
public:
    void print();
};

class Cat : private CatBase
{
public:
    void walk();

    CatBase* operator->() { return this; }
    const CatBase* operator->() const { return this; }
};
如果可以将print移动到基类,则非常简单:

class CatBase
{
public:
    void print();
};

class Cat : private CatBase
{
public:
    void walk();

    CatBase* operator->() { return this; }
    const CatBase* operator->() const { return this; }
};

可以使用虚拟返回对象重载->运算符。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;
}

可以使用虚拟返回对象重载->运算符。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;
}


如果你调用Cat的其他方法呢?@IvayloStrandjev:就像在Cat类中一样。更新了示例。这有点低效,因为每个Cat实例现在都包含一个CatAccessor。我认为可以通过从operator->返回一个CatAccessor实例,并使用operator->的chaining属性将另一个operator->添加到CatAccessor来改进。如果调用Cat的任何其他方法如何?@IvayloStrandjev:就像通过Cat类一样。更新了示例。这有点低效,因为每个Cat实例现在都包含一个CatAccessor。我认为可以通过从运算符返回一个CATAccess实例来改进,并使用操作符-Cuin的链接属性添加另一个操作符> Cad Access。下拉您可以指出我的答案中有什么不正确吗?C++允许您这样做,就像DanielFrey和我所展示的那样。因此,我认为答案是错误的。@ THITNN请提供一个完整的和可编译的代码来做你建议的下沉者,你能指出我的答案中有什么不正确吗?C++允许你这样做,就像DanielFrey和我所展示的那样。因此,我认为答案是错误的。@thiton请提供一个完整且可编译的代码,以完成您的任务suggest@DanielFrey:好办法。如果您将CatBase设置为私人基地,则可以满足打印不可直接调用的要求。@thiton:的确,这主意不错!编辑。谢谢@丹尼尔弗里:很好的方法。如果您将CatBase设置为私人基地,则可以满足打印不可直接调用的要求。@thiton:的确,这主意不错!编辑。谢谢猫*猫;cat->print;那么这到底应该做什么呢?不应该编译还是什么?请注意,当->的左侧是指针时,箭头运算符始终具有其内置含义,并且没有运算符->会更改表达式的含义。Cat*Cat;cat->print;那么这到底应该做什么呢?不应该编译还是什么?请注意,当->的左侧是指针时,箭头运算符始终具有其内置含义,并且没有运算符->会更改表达式的含义。