首页 > 解决方案 > 有没有办法在重载的运算符函数中达到默认运算符函数?

问题描述

我想包装一个运算符函数并重载它以进行调试。

例如:我想计算在 Foo 对象的程序运行期间完成了多少 = 操作。

static int counter = 0;
Foo operator=(const Foo& b) 
{
    //Somehow call default functionality of = opreator for foo.

    counter++;
}

重载运算符时是否可以仅调用运算符的默认功能。就像在编写重写函数时调用重写函数的基函数一样。

标签: c++

解决方案


如果通过“默认操作员功能”,您的意思是您想要operator=()做的所有事情,如果您只是做了

Foo &operator=(const Foo &) = default;

但是,此外,增加一个计数器,则没有直接的方法,因为这样的运算符只能有一个定义。

但是,您可以通过使用类似的东西来实现类似的效果

class Counter
{
     public:

          Counter &operator=(const Counter &) {++counter; return *this;};

          static int Count() {return counter;};
     private:
          static int counter;
};

并且(在具有类定义可见性的一个编译单元中,Counter 例如通过包含包含类定义的标头)做

int Counter::counter = 0;

然后只需添加一个Counter作为类的私有非静态成员Foo。这样,operator=()类中“默认”的每次使用Foo都会增加Counter::counter.

如果您的班级Foo是唯一使用 a 的地方,那么上面将允许计算分配Countera 的次数。Foo获取计数所需要做的就是随时调用Counter::Count()

正如 Caleth 在评论中所指出的,该类Counter可以在类型上进行模板化,因此Foo可以为与其他类建立不同的计数器。这也为使用 CRTP(Curiously Recurring Template Pattern)打开了大门,Foo可以从中派生Counter<Foo>以提供所需的功能。

有一些潜在的警告需要注意;

  • a 的大小Counter将非零,因此 a 的大小Foo可能会改变。
  • 您将需要确保类的构造函数和析构函数Counter (无论它们是如何定义的)与Foo;
  • 如果溢出,行为将是未定义Counter::count的(这限制了您的类可以分配的次数);
  • 没有什么可以阻止其他代码实例化和分配 a Count,这会弄乱你的计数(尽管如果Counter有所有成员private并将类指定Foo为 a ,这种可能性可能会减轻(注意我没有说“反击” friend)。

推荐阅读