Intercept C ++ Bcc Designer or call its functionality

Given:

class Foo { private: static int cntFoos; //... stuff... public: Foo() { cntFoos++; } ~Foo() { cntFoos--; } }; 

... where "stuff" can be any set of properties. (The idea is to have an instance counter of this class)

Then:

 Foo aFoo; Foo twoFoo=aFoo; 

Will call the automatic copy constructor, and so I would skip counting this.

Is there a way to keep this counter reflecting new instances created automatically? If I implement an explicit copy constructor, I will have to assign all the properties one by one. However, I want a shallow, in-place copy. I don't need to do a deep copy, so it seems like a lot of unnecessary work to implement an explicit copy constructor.

+5
source share
2 answers

Since most participants require default behavior and only require special processing for one (static) member, why not encapsulate this special processing in their class and make the member variable of this class? Like this:

 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; }; 

Implementation notes:

  • I created an InstanceCounter template so that different classes can easily have their own instance instances.
  • For C ++ 11, you'll also want to provide a move constructor and a move assignment operator for InstanceCounter .

Alternatively and probably better, using the CRTP idiom:

 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. 
+5
source

Sorry, you have to overload and copy manually.

If you really, really, are against this, you can use a hack in which you create an abstract parent class with a static counter and an overridden copy constructor, and a child class with your actual data members and an implicit incomplete copy constructor.

You can also use a slightly less hacky approach to the encapsulated class. Save the values ​​that you want to copy in the encapsulated class, and then, when implementing the constructor for explicit instances of the outer class, make a shallow copy of the inner class using its implicit copy constructor.

+5
source

Source: https://habr.com/ru/post/1208384/


All Articles