2014-11-28 21 views
6

iki nesne arasındaki karşılaştırma yapabilmek için ihtiyacı olan bir sınıf şablonu sahip şablon türleri zorlamak özel bir sınıf ile bu derlemeye çalıştığınızda birsahip olmadığı, ancakŞartlı ben bir <code>Compare</code> sınıfından türetilen karşılaştırma nesneleri ile, C++

template<typename A, typename B> 
    class Default : public Compare<A,B> { 
    public: 
     bool eq(const A& a, const B& b) const { return a==b; } 
    }; 
private: 
    Compare<T,T>* comparison_object; 
    bool uses_default; 
    Container() : comparison_object(new Default<T,T>()), uses_default(true) {} 
    Container(Compare<T,T>& cmp) : comparison_object(&cmp), uses_default(false) {} 
    ~Container() { if(uses_default) delete comparison_object; } 
}; 

: varsayarak tip T operatörü == sahiptiraşırı yük (I Compare türetilmiş bir nesne sağlamak bile):

MyObjCmp moc; 
Container<MyObj>(&moc); 

derleyici operatör var olmadığını yakınır:

error: no match for 'operator==' (operand types are 'const MyObj' and 'const MyObj') 

Bu mantıklı, Default sınıf hala gerektiğinden İhtiyacım olmasa bile oluşturulsun. Ama şimdi bir geçici çözümüme ihtiyacım var ...

Herhangi bir fikrin var mı? bir boş gösterici bir çalışma zamanı çek, hiçbir nesne için bir derleme zamanı çek kullanabilirsiniz yerine

+0

'Karşılaştır * comparison_object;' Bellek sızıntısına neden olur. Lütfen "new"/'delete 'yerine' std :: unique_ptr' veya' std :: shared_ptr' komutunu kullanın. – ikh

+1

Benim destroy'um ilgilenir ... "default_created" bir boole bayrağı ve koşullu silme Endişelenme :) – Dori

+0

@Niall, Düzenleyeceğim ... Olumsuz olduğunu düşündüm – Dori

cevap

4

:

Container() : comparison_object(new Default<T,T>), uses_default(true) {} 
Container(Compare<T,T>& cmp) : comparison_object(&cmp), uses_default(false) {} 

varsayılan yapıcı ve gerekirse dolayısıyla Default, sadece örneği olacak, Bu nedenle, varsayılan olmayan yapıcıyı Default'un başarısız olduğu bir türle kullanırken hata olmaz.

Ancak ham işaretçiler gibi dikkatli bir şekilde dikkatli olun, bellek sızıntıları ve daha kötü bir reçete. Compare ve Rule of Three için sanal yıkıcıyı unutmayın ve varsayılan olmayan bir karşılaştırıcının beklenmedik şekilde yok edilmemesi konusunda çok dikkatli olun. Daha da iyisi, sizin için tüm bunlara dikkat etmek için bir akıllı işaretçi kullanın.

+0

'a bile izin vermezler. Fakat yine de ikinci kurucuda NULL'u kontrol etmem gerekiyor ve gerekiyorsa "Varsayılan " ...silbaştan bir – Dori

+0

@Dori: Doğrusu ben bunu null olamaz sağlamak için, bir başvuru yerine bir işaretçi almak gerektiğini söylemeyi unutmuşum. Varsayılan karşılaştırıcıyı isterseniz, varsayılan kurucuyu kullanın. –

+0

Hayır. derleyici bu satırı okur da, böyle olmaz, 'Standart' örneğini edeceğiz? – ikh

0
template<typename T1, typename T2 > 
class Container { 
public: 
    template<typename T3, typename T4 > 
    class Compare { 
    public: 
     virtual bool eq(const T1&, const T2&) const = 0; 
    }; 


    class Default : public Compare { 
    public: 
     bool eq(const T1& a, const T2& b) const { return a==b; } 
    }; 

private: 
    Compare<T1,T2>* comparison_object; 
    bool uses_default; 
    Container(Compare<T1,T2>* cmp) : comparison_object(cmp), uses_default(false) { 
     if (!cmp) { 
      comparison_object = new Default<T,T>(); 
      uses_default = true; 
     } 
    } 
    ~Container() { if(uses_default) delete comparison_object; } 
};