2011-07-12 24 views
17

Çoğu durumda, soru kendiliğinden sorulmaz; çünkü bazen miras, hangi şablonların sağlayamayacağı gerekli özellikleri sağlar. Örneğin, bir farklı tür (polimorfizm) üzerinden farklı türlere hitap etmem gerektiğinde, kalıtımı kullanmam gerekir. Bununla birlikte, sorunun hem kalıtımla hem de şablonlarla çözülebileceği bazı durumlar vardır.Kalıtım yerine şablonları ne zaman kullanmalıyım?

bir dosya ayrıştırıcı

bir çözüm gibi görünebilir:

kodun belirli bölümlerinin örneği stratejisi desen benzeri parametreyle belirtme atın

ParsingAlgorithm soyut bir temel sınıftır
class FileParser 
{ 
    //... 
    public: 
     void Parse(ParsingAlgorithm* p); 
    //... 
} 

void FileParser::Parse(ParsingAlgorithm* p) 
{ 
    m_whatevertypeofvaluesineed = p->Parse(whateverparametersyouneed); 
} 

, FileParser sınıfı için belirli bir ayrıştırıcıyı kullanmayı seven herkesin miras alması gereken bazı temel yöntemler ve gereksinimler sağlar.

Ancak, aynı kolaylıkla elde edilebilir kullanarak şablonlar:

template <class Parser> 
class FileParser 
{ 
    //... 
    public: 
     void Parse() 
     { 
      m_whatevertypeofvaluesineed = m_parser.Parse(whateverparametersyouneed); 
     } 

    private: 
     Parser m_parser; 
    //... 
} 

Ben şablonlar veya devralma kullanıp kullanmayacağına karar için kullanabileceğiniz bazı genel kurallar var mıdır? Ya da sanal işlevler gibi şeylerin çalışma zamanı yükünü önlemek için mümkün olduğunca şablonları kullanmalı mıyım? miras tarafından sağlanan çalıştırma polimorfizmi aksine

+0

[Daha fazla tasarım için sanal işlevselliği tamamen değiştirebilir miyim?] [Http://stackoverflow.com/questions/6613779/can-crtp-completely-replace-virtual-functionality-for-smaller-designs) – iammilind

cevap

17

Derleme sırasında hangi nesneleri kullanacağınızı biliyorsanız, şablonlara sahip statik polimorfizm genellikle en hızlı yoldur ve biraz daha özlü kodlar üretir (açık mirasa gerek yoktur) . Güçlü bir sınıf hiyerarşisi ile sınırlı olmadığınız için daha genel olabilir.

Çalışma zamanı polimorfizmi istiyorsanız, sanal işlevlerin işaretçileri, kalıtımı ve hafif ek yüklerini kullanmaktan başka seçeneğiniz yoktur.

Kendi görüşüm:

  • şablonları kullanın, bu kodu (ama heterojen koleksiyonları sahip olmamak) Factorise fakat dilimleme ile dikkatli olmak
  • Kullanım miras rahat mümkün.
  • sanal aramalar Bazen
  • Başka seçeneğin var ve daha beri,
4

Şablonlar derleme polimorfizm sağlar. Yapabileceğim zaman şablonları kullanmayı tercih ederim.

Bu makalede, Templates and Inheritance ayrıntılı olarak açıklanmaktadır.

-1

Benim önerim, bu durumda hiçbirini kullanmamak ve her dosya türü için ayrı işlevleri kullanmak;

Stream stream = open(filepath); 

    Image image = ParseBMP(stream); 
    // ...or 
    Image image = ParseJPG(stream); 

İşleri olduğundan daha karmaşık hale getirmeye gerek yoktur.

+0

Haklısınız, ama benim örneğimin "miras vs şablonlar" sorununun ortaya çıkabileceği durumun hızlı bir örneği olması gerekiyordu. – TravisG

+0

Katılıyorum. Farklı işlevleri kullanmak, açık-kapanış ilkesine karşıdır. Http://en.wikipedia.org/wiki/Open/closed_principle –

+0

Daha önce bu prensibi hiç duymadım, ama benim için kötülük gibi görünüyor. –

3

Şablonlar, genellikle zamanında daha fazla ölçülebilir olan kullanan işaretçiler acısı etrafında sürükleyerek hetergenous koleksiyonunuzu istediğiniz performansı konularında endişe etmeyin iş derleme zamanında yapılır.Öte yandan, daha karmaşık, bu yüzden yazmak ve anlamak zor olabilir. Bu nedenle, tüm çözümü aşırı karmaşık hale getirmediğinde ve'u kullanabilmeniz en iyisidir. senin örnekleri için

, bunlar tam işlevsel olarak eşdeğer değildir: İlk varyant izin verir ve ikinci varyant o kodu yazdığında programcı tarafından seçilecek ayrıştırıcı gerektirir oysa, çalışma zamanında bir ayrıştırıcı örneğini oluşturmak gerektirir.

İlgili konular