2012-06-03 26 views
7

Birisi aşağıdaki kodun neden "sınıf B :: 1" olacağını açıklayabilir mi?Kod, türetilmiş sınıf yöntemini çalıştırır, ancak temel parametre yönteminden varsayılan parametre alır

Neden türetilen sınıf sanal yöntemi, temel bir sınıfın varsayılan parametresini kullanır ve kendi başına kullanır? Benim için bu oldukça garip. Şimdiden teşekkürler!

Kodu: varsayılan değer derleme sırasında ikame edilir ve gerçek işlevi (A :: fonk veya B :: fonk) çağrılacak ise zamanında tespit edilir, beyan alınır

#include <iostream> 

using namespace std; 

class A 
{ 
public: 
    virtual void func(int a = 1) 
    { 
     cout << "class A::" << a; 
    } 
}; 

class B : public A 
{ 
public: 
    virtual void func(int a = 2) 
    { 
     cout << "class B::" << a; 
    } 
}; 

int main() 
{ 
    A * a = new B; 
    a->func(); 

    return 0; 
} 

cevap

6

Varsayılan değişkenler statik türüne göre çözümlendiğinden this (yani, değişkenin kendisinin türü, A& a;'da A& gibi).

hafifçe örneğini değiştirme:

#include <iostream> 

class A 
{ 
public: 
    virtual void func(int a = 1) 
    { 
     std::cout << "class A::" << a << "\n"; 
    } 
}; 

class B : public A 
{ 
public: 
    virtual void func(int a = 2) 
    { 
     std::cout << "class B::" << a << "\n"; 
    } 
}; 

void func(A& a) { a.func(); } 

int main() 
{ 
    B b; 
    func(b); 
    b.func(); 

    return 0; 
} 

Biz şu çıktıyı gözlemek: Eylem olarak

class B::1 
class B::2 

ideone de.

Bu nedenle bir sanal işlevin varsayılan değeri değiştirmesi önerilmez. Ne yazık ki bu yapıyı uyarıcı herhangi bir derleyici bilmiyorum.

  • trambolin gibi davranmaya yeni işlev oluşturmak:


    teknik explication varsayılan argüman ile uğraşan iki yolu olmasıdır void A::func() { func(1); }

  • Eklenti ortadan kayboldu argüman Alanı a.func() =>a.func(/*magic*/1)

bu eski olsaydı (ve varsayarak A::func ağırlık virtual da belirtildiği gibi), beklediğiniz gibi çalışır. Ancak, bu sonuncusu, ya o zamanlar virtual ile ilgili sorunlar öngörülmediği için ya da faydalar karşısında (eğer varsa) önemsiz kabul edildiği için seçildi.

5

için.

+0

Hızlı cevap için teşekkürler! – Aremyst

5

C++ 'daki polimorfizm çalışma zamanında etkili olduğu için, varsayılan parametrelerin değiştirilmesi derleme zamanında etkili olur. Derleme zamanında derleyici, a işaretçisinin bulunduğu nesnenin dinamik türünü bilmez (ve bilmemesi gerekir). Bu nedenle, örneğinizde A * olan a için bildiği tek tür için varsayılan argümanı alır.

(Bu arada da parametreler yerine uygulamalar/tanımlarında daha arayüzleri/başlıklarında verilmiştir nedeni varsayılan değerdir. Derleyici ama sadece arayanın makine kodunda, uygulama makine kodunda varsayılan parametre ekler olmadı. Teknik olarak , varsayılan parametre arayanın özelliğidir ve arayanın bilmediği - ve bilmesi gerekmemesi gereken - bir nesnenin dinamik türü.)

+0

Cevabınız çok açık, teşekkürler! – Aremyst