2013-04-05 36 views
5

Genellikle kodumun düzgün çalışması için gerekli olan yöntemler için salt sanal işlevler kullanıyorum. Bu yüzden, arayüzler oluşturuyorum ve diğer kullanıcılar türetilmiş sınıflarını uyguluyorum. Türetilmiş sınıflar yalnızca kamuya açık olan bu sanal işlevlere sahipken, kodum onları aramadığı için bazı ek yöntemler özel olarak uygulanmalıdır. Bunun iyi bir OOP uygulaması olarak kabul edilip edilemeyeceğini bilmiyorum (herhangi bir desen var mı?). Neyse, sorum şu: Bir kullanıcı saf sanal işlevi aşırı yükleyebilir mi? temel sınıfSaf sanal işlevin aşırı yüklenmesi

virtual void foo(int,double,double=0)=0; 

ama çok sınırlıdır:

yani

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
}; 

class Derived: 
public Base 
{ 
private: 
    // methods 
public: 
Derived(); 
virtual ~Derived(); 
virtual void foo(int, double, double); //this doesn't work 
}; 

bir çözelti olabilir. Ne hakkında düşünüyorsun?

+1

Fonksiyon aşırı yükler ** bir ** farklı API temsil eder. Soyut bir temel sınıf ** tutarlı bir API ** temsil eder. Yani hayır, bu mantıklı değil. –

+0

Örneğiniz 'class Derived: Base' eksik değil mi? – nonsensickle

+0

@nonsensical: doğru, daha yeni düzenledim. teşekkürler – Ale

cevap

9

Bu 2 işlev farklıdır. İkincisi, ilk olarak, türetilene özgü yeni sanal işlevdir.

Sonunda bir override koyarsanız derleme, hiçbir şeyi geçersiz kılmayacağınızdan şikayet eder. Bu C++ 11 kontrol olsa da.

virtual void foo(int, double, double) override; 

kullanıcı doğrulamak için işlevi sonunda kullanımını override onaylamak için saf sanal fonksiyon geçersiz kılabilir. Sizin durumunuzda ikinci fonksiyona sadece Türetilmiş işaretçi veya tip kullanılarak erişilebilir. (salt sanal işlev düzgün bir şekilde geçersiz kılmadıkça ve uygulanamadığı sürece, örneklenemese de, o zamana kadar soyut bir sınıftır). Bu nedenle, Derived'dan türeyen sınıflar tarafından overidden edilmek üzere tasarlanmamışsa, o zaman sanal hale getirmek, temel metodu aşmamakta olduğu için yine de bir yük olmaktadır.

+0

Bu cevap atıldığında sadece 'geçersiz kıl' hakkında yazıyordum. http://msdn.microsoft.com/en-us/library/vstudio/jj678987.aspx – Kupto

+0

@Kupto: Yani burada en azından bağlantıyı gider örnekte, öncelikle funcC (çift = 0.0) geçersiz kılma çalışır neden ise ikinci kod çalışmıyor? – Ale

+0

@Ale Sadece denedim ve yorumların dikkate alınması durumunda, ilk örnekteki "geçersiz kıl" anahtar kelimesinin gereksiz olduğu anlaşılıyor. – Kupto

4

Yapamazsınız.

nesnesini işaret eden bir Base işaretçiniz olduğunu varsayalım. Base işaretçisine sahip olduğunuzda, yalnızca Base arabirimine "erişim" seçeneğiniz vardır (Derived işaretçisine atmadığınız sürece, bu sizin ihtiyacınız olan şey değildir).

+0

evet, bu bir problem. Dolayısıyla tek çözüm, bir sınıf değil, bir arayüz oluşturur. Öyle değil mi? – Ale

+0

@Ale - Ben senin noktanı anlamıyorum. C++ 'arayüzü' ve 'soyut sınıf' arasındaki fark nedir? –

+0

[link] (http://stackoverflow.com/questions/15387581/more-methods-in-derived-classes-than-base-class) türetilmiş bir sınıf, soyut sınıftan daha fazla işleve sahip olabilir. Bunun yerine bir arabirim, yöntemlerin sayısını sınırlar (benim görüşüme göre). – Ale

3

Aşırı yüklenmiş bir işlev, yalnızca bir başkasıyla aynı ada sahip bir işlevdir, ancak farklı bir parametre kümesini kabul eder, yani farklı işlevidir. Bir veya daha fazla aşırı yüklenmiş fonksiyonun sanal olup olmadığı ile ilgisi yoktur.

Sunulan örnekte, bir kullanıcının salt sanal işlevi aşırı yükleyebildiğine inanıyorum, ancak yalnızca bunu geçersiz kıldıktan sonra. Ve doğrudan temel sınıftaki işleve erişemiyordunuz - temel sınıf göstergesini türetilmiş sınıf işaretçisine dökmeniz gerekir.

0

Başkaları tarafından da işaret edildiği gibi, sadece işe yaramaz.

Daha Discretely, burada fonksiyon imzalar farklı gibi baskın olmadığından

Derived d; 
d.foo(5, 10.0); // Works as expected 

Base &b = d; // b is polymorphic 
b.foo(3,10,4); // foo(int, double, double) is not in class Base, hence compile-time resolution fails! 
0

ne olduğudur.Polimorfizm kuralına göre bir işlevi geçersiz kılmak için fonksiyon imzaları ve türleri aynı olmalıdır.

Bu durumda bu işlevler farklıdır. sanal geçersiz foo (int, çift) = 0; sanal geçersiz foo (int, çift, çift);

0

kolay çözüm taban sınıftaki foo aşırı değil mi?

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
virtual void foo(int,double,double)=0; 
}; 
İlgili konular