【问题标题】:Overloading operator for a function call函数调用的重载运算符
【发布时间】:2013-03-11 19:12:05
【问题描述】:

是否可以只为一个函数重载一个运算符。我想覆盖 '->' 运算符,但仅在使用 print 函数( ->print() )调用它时。我知道这是一个奇怪的请求,但我正在努力实现某个 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->print(); 那么这到底应该做什么呢?不应该编译还是什么?
  • 注意当->的左边是指针时,箭头操作符总是有它的内置含义,没有operator->会改变表达式的含义。

标签: c++ operator-overloading overloading


【解决方案1】:

您可以使用虚拟返回对象重载 -> 运算符。真正的 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-&gt; 返回一个CatAccessor 实例并使用operator-&gt; 的链接属性将另一个operator-&gt; 添加到CatAccessor 来改进它。
【解决方案2】:

如果您可以将print() 移动到基类,那就很简单了:

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

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

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

【讨论】:

  • @DanielFrey:不错的方法。如果您将CatBase 设为私有基地,则可以满足 print() 不可直接调用的要求。
  • @thiton:确实,好主意!编辑。谢谢!
【解决方案3】:

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

【讨论】:

  • downvoter 你能指出我的回答有什么不正确吗?
  • C++ 确实允许您这样做,正如 DanielFrey 和我所展示的那样。因此,我认为答案是错误的。
  • @thiton 请提供完整且可编译的代码,以执行您的建议
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多