我正在读这篇文章 Overriding vs method hiding
我读到了“ ..当在对象上调用虚方法时,该方法的派生版本最多被称为”
但是当我执行以下代码时:
struct C : A, B {
C& operator=(C&& c) {
static_cast<A&>(*this) = static_cast<A&&>(c);
return *this;
}
};
打印B。如果以上引用的陈述是真的,它不应该是“C”吗? 我错过了什么?在这种情况下,“大多数派生”是什么意思?
答案 0 :(得分:1)
它将从调用它的实例的类型调用方法,您使用类B
的实例调用它,因此如果您使用类的实例,将调用B
的实现<{1}}然后会调用C
类的重写实现。
例如:
C
现在如果你这样称呼它:
class B :A
{
public override void print()
{
Console.WriteLine("B called");
Console.Read();
}
public virtual void printfromB()
{
Console.WriteLine("printfromB in B called");
Console.Read();
}
}
class C : B
{
public override void print()
{
Console.WriteLine("C called");
Console.Read();
}
public override void printfromB()
{
Console.WriteLine("printfromB in C called");
Console.Read();
}
}
答案 1 :(得分:0)
当实际类型为C
时,无法调用B
。
原始的“大多数派生”术语可以使用以下内容来理解:
A data = new C();
data.print();
即使编译器将data
视为A
,派生的(不是A.print
或B.print
,但是C.print
)将调用版本(这是因为该方法是virtual
)。
请参阅Polymorphism
答案 2 :(得分:0)
我认为你对答案中单词的技术性感到困惑。
这里有两件事,
如果你这样做,
A a = new B();
a. print(); // this will invoke the method on the class B,
// since instance of class A has reference to instance of B.
如果您执行以下操作:
A a = new C();
a. print(); // Should call the method on class C, since base class has reference to to the instance of C.
同样,更直观的方式是:
A a = new A();
a.print(); // this will call the method print in class A irrespective of whether this method was overriden in one of the derived classes.
这是动态多态的前提,其中,客户端可以在A的基类对象上调用方法print() 无需知道A是否引用了B或C.行为在客户端代码中动态变化。
假设方法print()未在C中覆盖,但在B中被覆盖, 那么print()的派生版本将在B类中。以下片段应该会有所帮助。
class A
{
public virtual void print()
{
Console.WriteLine("A called");
Console.Read();
}
}
class B :A
{
public override void print()
{
Console.WriteLine("B called");
Console.Read();
}
}
class C : B
{
public void somerandommethod()
{
// some random method not really relevant to this example.
}
}
static void Main(string[] args)
{
A a = new C();
a.print(); // it will now print B (since B has the most derived implementation of print())
}
希望这个答案有所帮助。
最佳。