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

标签 c++ copy-constructor shallow-copy default-copy-constructor

给定:

class Foo {

private:
    static int cntFoos;

    //... stuff...

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

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

然后:

Foo aFoo;
Foo twoFoo=aFoo;

将调用自动复制构造函数,因此我会错过计算这个。

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

最佳答案

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

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.

关于c++ - 拦截 C++ 隐式复制构造函数,或调用其功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27303251/

相关文章:

c++ - 线程更新类对象

c++ - 为什么我们把 & 放在复制构造函数中?

c++ - 带有受歧视 union 和可选<>的奇怪段错误

c++ - 为什么在这种情况下不调用复制构造函数?

python - 为什么要为自己设置一个字典浅拷贝?

c++ - C++ 11多线程生产者/消费者程序挂起

c++ - 在 Visual Studio 10 中使用类型转换运算符重载时出现 C2440 错误

C++ 类库动态运行时分配

python - 为什么我应该制作数据框的*浅*副本?

c++ - 在仅 move 类型上强制复制(然后销毁)