ben, birden mirastan taban sınıflarına virtual
yöntem ve işaretçileri beklemiyorduk bir sonuç var. d.getStr()
ileÇoklu kalıtım, sanal metotlar çarpışma ve işaretçileri
, d
bir derived
örneğidir zaman beklendiği gibi base_2
sürümü denir. Beklendiği gibi p
bir derived
örneği (ya da derived
örneğine işaret base_2
bir işaretçi) bir işaretçidir p->getStr()
ile
, base_2
versiyonu, olarak adlandırılır.
Ama p
bir derived
örneğine işaret eden bir base_1
bir göstericidir p->getStr()
ile
base_1
sürümü denir ve ben
base_2
versiyonunu aranmak ikna oldu (teşekkürler
using
ve
getStr()
virtual
yöntemler olması) .
Aşağıdaki basit bir örnek:
#include <iostream>
struct base_1
{
virtual std::string getStr() const
{ return "string from base 1"; }
};
struct base_2
{
virtual std::string getStr() const
{ return "string from base 2"; }
};
struct derived : public base_1, public base_2
{
using base_2::getStr;
};
int main()
{
derived d;
derived * dp = &d;
base_1 * bp1 = &d;
base_2 * bp2 = &d;
std::cout << "from derived: " << d.getStr() << std::endl;
std::cout << "from derived pointer: " << dp->getStr() << std::endl;
std::cout << "from base_1 pointer: " << bp1->getStr() << std::endl;
std::cout << "from base_2 pointer: " << bp2->getStr() << std::endl;
}
çıkışı
Benbase_2
versiyonunun çağrıyı empoze etmek, biliyoruz
from derived: string from base 2
from derived pointer: string from base 2
from base_1 pointer: string from base 1
from base_2 pointer: string from base 2
, ben derived
aşağıdaki yöntem de ekleyebilirsiniz aşağıdaki
std::string getStr() const
{ return base_2::getStr(); }
ama sorularım şunlardır:
1) Neden base_1
(türetilmiş bir örneğine işaret) için işaretçi using
direktifini göz ardı edip getStr()
ait base_1
versiyonunu diyor?
2) getStr()
arasında base_2
versiyonu empoze bir yol var, derived
örneği getStr()
yeniden tanımlayarak olmadan base_1
işaretçi tarafından kullanılır?
--- DÜZENLEME --- cevapları için
teşekkürler.
Sana oluyor ama benim şüphe ne açıklayan anlıyoruz: Dil (standart) bu yönünü tarif ediyor? Yoksa tanımlanmamış bir bölüm mü?
Yani: Ne using
yönergesi kaldırırsanız derleyici seçti getStr()
hangi sürümünü bilmediği için, ben d.getStr()
gelen ve dp->getStr()
bir derleme hatası (error: request for member getStr is ambiguous
), olsun.
Ama getStr()
virtual
yöntemlerdir. Yani (bunu ikna ettim) bir taban işaretçisinin türetilmiş sürümünü kullanması gerekir. Ama birkaç çarpışma metodumuz var.Görüş dil (standart) noktadan
base_1
(veya
base_2
) işaretçi diğer görmezden çarpışan yöntemlerinin iki sürümlerinden birini seçmek için yetkili (veya yükümlü) nedir?
Belki yanılıyorsunuz ama bana göre virtual
yöntemleri virtual
yöntemleri olarak yönetiliyor.
'using' yalnızca görünürlük içinde yardımcı olur. Temel sanal işlevden 'aşırı yüklenme' yapmaz veya ona benzemez. – Arunmu