繁体   English   中英

拦截C ++隐式复制构造函数,或调用其功能

[英]Intercept C++ implicit copy constructor, or invoke its functionality

鉴于:

class Foo {

private:
    static int cntFoos;

    //... stuff...

public:
     Foo() { cntFoos++; }
     ~Foo() { cntFoos--; }
};

......“stuff”可以是任何属性集。 (想法是有一个该类实例的计数器)

然后:

Foo aFoo;
Foo twoFoo=aFoo;

将调用自动复制构造函数,因此我会想念这个。

有没有办法让该计数器反映自动创建的新实例? 如果我实现显式复制构造函数,我将不得不逐个分配所有属性。 但是,我想要一个浅的成员副本。 我不需要执行深层复制,因此实现显式复制构造函数似乎需要做很多工作。

对不起,您需要手动超载和复印。

如果你真的,真的,真的反对这个,你可以使用hack来创建一个带有静态计数器和重写的复制构造函数的抽象父类,以及一个带有实际数据成员和隐式浅复制构造函数的子类。

您也可以采用封装类的稍微不那么苛刻的方法。 将要复制的值存储在封装类中,然后在实现外部类显式复制构造函数时,使用其隐式复制构造函数生成内部类的浅表副本。

由于您需要大多数成员的默认行为,并且只需要对一个(静态)成员进行特殊处理,为什么不将该特殊处理封装在自己的类中并创建该类的成员变量? 像这样:

template<typename T>
class InstanceCounter
{
public:
  static int Count;

  // Automatically invoked when a class containing it is created.
  InstanceCounter() { Count++; }

  // Automatically invoked when a class containing it is destroyed.
  ~InstanceCounter() { Count--; }

  // Automatically invoked when a class containing it is copy-constructed.
  InstanceCounter(const InstanceCounter& rhs) { Count++; }

  // No need to override operator=

  // Allow this counter to be used as an int.    
  operator int() const { return Count; }
};

template<typename T>
int InstanceCounter<T>::Count;

class Foo
{
public:
  InstanceCounter<Foo> count;
};

实施说明:

  • 我使InstanceCounter成为一个模板,以便不同的类可以轻松拥有自己的实例计数。
  • 对于C ++ 11,您还需要为InstanceCounter提供移动构造函数和移动赋值运算符。

或者,可能更好,使用CRTP习语:

template<typename T>
class InstanceCounted
{
public:
  static int InstanceCount;

  // Automatically invoked when a class containing it is created.
  InstanceCounted() { InstanceCount++; }

  // Automatically invoked when a class containing it is destroyed.
  ~InstanceCounted() { InstanceCount--; }

  // Automatically invoked when a class containing it is copy-constructed.
  InstanceCounted(const InstanceCounted& rhs) { InstanceCount++; }

  // No need to override operator=
};

template<typename T>
int InstanceCounted<T>::InstanceCount;

class Foo : public InstanceCounted<Foo>
{
  // insert class contents here
};
// Now we can access Foo::InstanceCount.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM