是否有一种方法可以在超载运算符函数中接触默认运算符函数

Is there a way to reach default operator function in overloaded operator function?

本文关键字:函数 运算符 超载 默认 接触 方法 一种 是否      更新时间:2023-10-16

我想将运算符功能包裹起来,以使其重载为调试目的。

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

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

在使运算符过载时可以仅调用默认功能。就像编写覆盖功能时覆盖功能的呼叫基本功能一样。

如果通过"默认运算符函数",您的意思是您希望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;
};

and(在一个恰好具有Counter类定义的汇编单元中

int Counter::counter = 0;

然后,只需将单个Counter添加为类Foo的私人非静态成员。这样,Foo类中"违约" operator=()的每一个用法都会增加Counter::counter

如果您的类Foo是使用Counter的唯一位置,则以上将允许计算分配Foo的次数。您需要做的所有需要做的就是调用Counter::Count()

正如Caleth在评论中指出的那样,可以在类型上模板Counter类,因此可以建立Foo与其他类别的柜台。这也打开了使用CRTP(奇怪的重复模板模式(的门,其中Foo可以从Counter<Foo>派生以提供所需的功能。

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

  • Counter的大小将是非零的,因此Foo的大小可能会更改。
  • 您将需要确保Counter类的构造函数和破坏者(但是,定义它们(与Foo;
  • 正确工作
  • 如果Counter::count溢出,该行为将不确定(限制可以分配课程的次数(;
  • 没有什么可以阻止其他代码实例化和分配Count,它会弄乱您的计数(尽管这种可能性如果Counter具有所有成员private并将类Foo指定为friend(。

如果提供自定义operator=实现,则编译器不会生成默认的一个。由于不存在,因此无法访问它。

我建议将一个单独的类operator=组成单独的类,并将其添加到class Foo中作为字段(或基类(。

这是一种介绍基于模板的分配运算符的方法,它不会超载默认一个:

static int counter;
struct Foo
{
    template<bool=false> Foo& operator=(const Foo& b)
    {
        // The non-debug one
        return operator=(b);
    }
    template<> Foo& operator=<true>(const Foo& b)
    {
        // The debug one
        ++counter;
        return operator=(b);
    }
};

然后您可以使用

Foo f;
Foo g;
g.operator=<>(f); // This is the non-debug one
g.operator=<true>(f); // This is the non-debug one
g.operator=<false>(f); // This is the debug one

您当然可以写g = f

不幸的是,尽管您不能在写作时写g=<false>f;,因此所设想的呼叫语法很难看。

注意:仅当复制构造函数完全执行副本分配运算符应该执行的操作时,这才能起作用(除了增加静态计数器外(。

Foo operator=(const Foo& b) 
{
    ++counter;
    //Somehow call default functionality of = opreator for foo.
    Foo copy(b);
    return copy;
    //counter++;
}

您可以在线查看我的代码。

我不确定使用此问题的其他陷阱,而不是顶部提到的陷阱。批评是最欢迎的。