SORU
19 EKİM 2010, Salı


Özel saf sanal işlevi ne anlamı var?

Bir üstbilgi dosyasında aşağıdaki kodu buldum

class Engine
{
public:
    void SetState( int var, bool val );
    {   SetStateBool( int var, bool val ); }

    void SetState( int var, int val );
    {   SetStateInt( int var, int val ); }
private:
    virtual void SetStateBool(int var, bool val ) = 0;    
    virtual void SetStateInt(int var, int val ) = 0;    
};

Benim için, bu da Engine Sınıf veya bir sınıf türetilmiş, o saf sanal işlevler için uygulanmasını sağlamak zorunda olduğu anlamına gelir. Türetilmiş sınıfları onları yeniden gerçeklemek için bu özel fonksiyonlara erişim düşünmemiştim ama neden onları sanal yapmak?

CEVAP
20 EKİM 2010, ÇARŞAMBA


Bu konudaki soru oldukça yaygın bir kafa karışıklığı gösteriyor. Karışıklık karışıklık kötü bir şey gibi görünüyordu, çünkü C FAQ özel sanal olanı, uzun süre kullanma karşı savunduğu ortak yeterli.

Karışıklık kurtulmak için: Evet, özel sanal fonksiyonlar, türetilmiş sınıflar içinde geçersiz kılınabilir. Türetilmiş sınıfların yöntemlerini temel sınıf sanal işlevleri çağıramaz, ama onlar için kendi uygulama sağlayabilir. Göre Herb Sutter, olması, halka açık olmayan sanal arabirim temel sınıf ve özel bir uygulama olabilir özel olarak türetilmiş sınıfları sağlar için daha iyi "ayrılık şartname arabirimi belirtimi uygulama özelleştirilebilir davranış". Yazısında "Virtuality" bu konuda daha fazla bilgi edinebilirsiniz.

Benim görüşüme göre sunulan, biraz daha ilgiyi hak bu kodu daha ilginç bir şey, ancak vardır. Ortak arabirim sanal olmayan ve bu işlevleri olmayan, açık çağrı, olmayan aşırı yüklenmiş fonksiyonlar sanal fonksiyonları bir dizi oluşur. B, her zamanki gibi bir deyim vardır, bir adı vardır, ve tabii ki yararlıdır. Adı (sürpriz, sürpriz!)

"Kamu Aşırı Olmayan Sanal Çağrı Korumalı Olmayan Aşırı Yüklü Sanal Olanı"

20* *yardımcı olur. Bu konuda daha fazla bilgi alabilirsiniz here, kısa zamanda açıklamaya çalışacağım.

Engine sınıfının sanal fonksiyon da arayüz ve saf sanal olmayan aşırı yüklü işlev grubu olduğunu düşünün. Eğer sanal saf olsalardı, hala aşağıda, ama alt sınıf hiyerarşisinde açıklandığı gibi aynı sorunla karşılaşıyoruz.

class Engine
{
public:
    virtual void SetState( int var, bool val ) {/*some implementation*/}
    virtual void SetState( int var, int val )  {/*some implementation*/}
};

Şimdi gelelim türetilmiş bir sınıf oluşturmak istediğinizi varsayalım ve bağımsız olarak iki değer vermez gereken yöntem, sadece yeni bir uygulama sağlamanız gerekir.

class MyTurbochargedV8 : public Engine
{
public:
    // To prevent SetState( int var, bool val ) from the base class,
    // from being hidden by the new implementation of the other overload (below),
    // you have to put using declaration in the derived class
    using Engine::SetState;

    void SetState( int var, int val )  {/*new implementation*/}
};

Eğer türetilmiş sınıf (veya ikinci aşırı tanımlamak için) kullanarak Bildirgesi koymayı unutmuşsun, senaryoda sorun altına alabilir.

MyTurbochargedV8* myV8 = new MyTurbochargedV8();
myV8->SetState(5, true);

Eğer Engine üyelerinin gizleme önlemek sormaman değil, deyim:

myV8->SetState(5, true);

arama ediyorum türetilmiş sınıf void SetState( int var, int val ), int 15 *dönüştürme.

Arayüzü sanal ve sanal uygulama halka açık olmayan, exmaple gibi, türetilmiş sınıf yazar, düşünmek için daha az sorun var ve sadece yazmak

class MyTurbochargedV8 : public Engine
{
private:
    void SetStateInt(int var, int val )  {/*new implementation*/}
};

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FOSDEM

    FOSDEM

    13 Ocak 2009
  • mipd1980

    mipd1980

    25 EKİM 2006
  • Motor Trend Channel

    Motor Trend

    11 Mart 2006