2010-01-29 30 views
21

C++ uygulamasında, bir temel sınıfın üye işlevi, prototip (parametrelerin sayısı, türü ve sıkılığı) farklı olsa bile, aynı adda türetilmiş sınıf işleviyle geçersiz kılınır mı? Bu çok saçma bir soru sanırım, çünkü birçok web sitesi, işlev prototipinin gerçekleşmesi için aynı olması gerektiğini söylüyor; ancak aşağıdaki kod neden derlenmiyor? Çok basit bir miras davası, inanıyorum.C++ devralma ve işlev geçersiz kılma

#include <iostream> 
using std::cout; 
using std::endl; 

class A {}; 
class B {}; 

class X 
{ 
public: 
    void spray(A&) 
    { 
     cout << "Class A" << endl; 
    } 
}; 

class Y : public X 
{ 
public: 
    void spray(B&) 
    { 
     cout << "Class B" << endl; 
    } 
}; 

int main() 
{ 
    A a; 
    B b; 
    Y y; 

    y.spray(a); 
    y.spray(b); 

    return 0; 
} 

GCC yüzden 'gizleme' denir

error: no matching function for call to `Y::spray(A&)' 
note: candidates are: void Y::spray(B&) 
+0

Bazılarının gerektirmesi durumunda ayrıntılı bir açıklama için aynı sorun hakkında yazan C++ SSS'i aldınız :) http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq- 23.9 – legends2k

+1

İmzaların aynı olması gerektiğini söylemek biraz tehlikelidir. İmzalar isimlendirme ve bağlamanın temelidir. Farklı sınıfların iki üyesi, biri diğerini geçersiz kılsa bile, her zaman farklı imzalara sahiptir. Söylemek daha uzun olsa bile, "aynı parametre türleri, isimler ve kabızlık" demek daha iyidir. –

+0

@litb: Netleştirmek için teşekkürler! Sanırım 'prototip' burada uygun kelimedir, ben bunu değiştirdim :) – legends2k

cevap

28

ziyade "ağır basan" den, bu "gizleme" olduğunu tanımlamak için kullanılan terim. Türetilmiş bir sınıfın bir üyesi, varsayılan olarak, aynı imzaya sahip olsun ya da olmasın, aynı adla erişilebilecek taban sınıflarının herhangi bir üyesini yapar. Temel sınıf üyelerine erişmek isterseniz, bunları bir using bildirimi ile türetilmiş sınıfa çekebilirsiniz. Bu durumda, class Y aşağıdakileri ekleyin:

using X::spray; 
+0

Açıkladığınız açıklama için teşekkürler. Buradaki kullanma yönergesini eklediğimde çalışır. Ancak sprey imzalarını X'de (int) püskürtmek ve Y'de sprey (float) olarak değiştirdiğimde ve y.spray (1) 'i çağırdığımda; ve y.spray (1.0f); kullanma yönergesi olmadan çalışır. Nasıl olur? – legends2k

+2

Vay üzgünüm, benim kötü, hala y.spray (1) yaptığımda Y'lerin spreyini (yüzdürme) görüyor; Bu yazı int dolaylı olarak yüzer. – legends2k

+2

Bu, kendi özel sorusunu hak eden ve insanların daha iyi bulabilmesi için birçok arama tozuyla hazırlanmış cevaplardan biri. – Wug

10

atar: Y::sprayX::spray gizler. yönergesini kullanarak Ekleme:

class Y : public X 
{ 
public: 
    using X::spray; 
    // ... 
}; 
5

Sınıflar kapsamları ve sınıf kapsamı ailesindeki yuvalanır. Diğer iç içe geçmiş kapsamlarda (ad alanları, bloklar) tam olarak aynı davranışın var.

İsim arama, bir adın tanımını aradığında, o anki ad alanında, sonra da ilgi çekici ad alanında ve bir tanıma bulana kadar görünür; arama daha sonra durur (argümana bağımlı isim arama ile ortaya çıkan komplikasyonları hesaba katmadan - argümanlarından birinin isminde tanımlanan bir işlevi kullanmasına izin veren kuralların bir kısmı).

+0

Bağlamanın ardındaki temel nedeni açıkladığınız için teşekkür ederiz; gerçekten bu hatayı neden aldığımı ve kullanım direktifinin neden bu sorunu çözdüğünü gerçekten söylüyor. – legends2k

İlgili konular