policy pattern und ref-counter



  • hallo

    da ein statischer member einer klasse ja je nach templateargument ein eigener ist (wegen der instanziierung) frage ich mich, wie ich gleichzeitig das policy pattern und einen reference counter implementieren kann. denn ich würde gerne den reference counter so machen, dass er über alle nicht-policy-template-parameter hinweg unterschiedlich ist, jedoch über die policy-template-parameter hinweg gleich.

    zur veranschaulichung:

    #include <iostream>
    using namespace std;
    struct policy_1
    {
    };
    struct policy_2
    {
    };
    template<class T, class policy = policy_1>
    struct foo
    {
    	static unsigned ref_counter;
    	foo()
    	{
    		ref_counter++;
    	}
    	~foo()
    	{
    		ref_counter--;
    	}
    	template<class rhs_policy>
    	foo(foo<T, rhs_policy> const& rhs)
    	{
    		ref_counter++;
    	}
    	template<class rhs_policy>
    	foo& operator= (foo<T, rhs_policy> const& rhs)
    	{
    	}
    };
    template<class T, class policy>
    unsigned foo<T, policy>::ref_counter;
    int main()
    {
    	foo<int> bar1;
    	cout << bar1.ref_counter << '\n'; // ausgabe: 1, gewünscht: 1
    	foo<float> bar2[2];
    	cout << bar2[0].ref_counter << '\n'; // ausgabe: 2, gewünscht: 2
    	foo<int, policy_2> bar3;
    	cout << bar3.ref_counter << '\n'; // ausgabe: 1, gewünscht: 2 (da selber parameter class T wie bar1)
    }
    


  • Der Trick ist, das Refcounting in eine Basisklasse auszulagern, die nicht von der Policy abhängt.

    using namespace std;
    struct policy_1
    {
    };
    struct policy_2
    {
    };
    
    template <class T>
    struct basic_foo {
      static unsigned ref_counter;
      basic_foo()
      {
        ref_counter++;
      }
      ~basic_foo()
      {
        ref_counter--;
      }
      basic_foo(basic_foo const& rhs)
      {
        ref_counter++;
      }
      basic_foo& operator= (basic_foo const& rhs)
      {
      }
    };
    
    template<class T, class policy = policy_1>
    struct foo : basic_foo<T>
    {
    };
    
    template<class T>
    unsigned basic_foo<T>::ref_counter;
    int main()
    {
      foo<int> bar1;
      cout << bar1.ref_counter << '\n';
      foo<float> bar2[2];
      cout << bar2[0].ref_counter << '\n';
      foo<int, policy_2> bar3;
      cout << bar3.ref_counter << '\n'; // jetzt wie gewünscht 2
    }
    

Anmelden zum Antworten