C++ C+中的继承和指针+;
我有这个代码示例,我想了解它为什么会这样做。这是一个在一个C++课程中的过去试卷的问题。我现在正在准备考试,并试图巩固我对阶级继承的理解C++ C+中的继承和指针+;,c++,inheritance,polymorphism,C++,Inheritance,Polymorphism,我有这个代码示例,我想了解它为什么会这样做。这是一个在一个C++课程中的过去试卷的问题。我现在正在准备考试,并试图巩固我对阶级继承的理解 #include <iostream> using namespace std; class Bird { public: virtual void noise() { cout << "mumble" << endl; } void move() { noise(); cout << "f
#include <iostream>
using namespace std;
class Bird {
public:
virtual void noise() { cout << "mumble" << endl; }
void move() { noise(); cout << "fly" << endl; }
};
class Canary: public Bird {
public:
void noise() { cout << "chirp" << endl; }
void move() { noise(); cout << "flap" << endl; }
};
class Tweety: public Canary {
public:
void noise() { cout << "tweet" << endl; }
void move() { noise(); cout << "run" << endl; }
};
int main() {
Canary *yellow = new Tweety();
yellow->noise();
yellow->move();
return 0;
}
这表示*黄色是一个金丝雀指针,它指向一个Tweety对象。我对此没有意见,因为我得到了指向基类的指针可以指向派生类的指针。但是*黄色指向Tweety,为什么不使用Tweety的move()
提前感谢您的帮助。移动()也应该是虚拟的,否则将调用指针类型的版本。移动()也应该是虚拟的,否则将调用指针类型的版本。
noise
是虚拟的,因此,当您调用它时,它被动态地分派到Tweety
实现
move
in not virtual,因此要调用的版本在编译时根据要通过的调用类型决定。由于yellow
是一个Canary
编译器会解析编译时将调用的内容,并且会显式调用Canary
中的move
方法,因为noise
是虚拟的,所以当您调用它时,它会动态地调度到Tweety
实现中
move
in not virtual,因此要调用的版本在编译时根据要通过的调用类型决定。由于yellow
是一个Canary
,编译器会解析编译时将调用的内容,并在Canary
中显式调用move
方法
下面是一些更多的调用案例,它们应该有助于理解不同的场景
#include <iostream>
using namespace std;
class Bird {
public:
virtual void noise() { cout << "mumble" << endl; }
void move() { noise(); cout << "fly" << endl; }
void noise2() { cout << "mumble2" << endl; }
virtual void move2() { noise2(); cout << "fly2" << endl; }
};
class Canary: public Bird {
public:
void noise() { cout << "chirp" << endl; }
void move() { noise(); cout << "flap" << endl; }
void noise2() { cout << "chirp2" << endl; }
void move2() { noise2(); cout << "flap2" << endl; }
};
class Tweety: public Canary {
public:
void noise() { cout << "tweet" << endl; }
void move() { noise(); cout << "run" << endl; }
void noise2() { cout << "tweet2" << endl; }
void move2() { noise2(); cout << "run2" << endl; }
};
int main() {
Canary *yellow = new Tweety();
yellow->noise();
yellow->move();
yellow->noise2();
yellow->move2();
return 0;
}
/* OUTPUT:
tweet <- virtual dispatch
tweet <- virtual dispatch, via Bird::move()
flap <- direct call
chirp2 <- direct call
tweet2 <- direct call, from Tweety::move2()
run2 <- virtual dispatch
*/
#包括
使用名称空间std;
班鸟{
公众:
虚拟虚空噪音(){coutSean和Alex很合适
下面是一些更多的调用案例,它们应该有助于理解不同的场景
#include <iostream>
using namespace std;
class Bird {
public:
virtual void noise() { cout << "mumble" << endl; }
void move() { noise(); cout << "fly" << endl; }
void noise2() { cout << "mumble2" << endl; }
virtual void move2() { noise2(); cout << "fly2" << endl; }
};
class Canary: public Bird {
public:
void noise() { cout << "chirp" << endl; }
void move() { noise(); cout << "flap" << endl; }
void noise2() { cout << "chirp2" << endl; }
void move2() { noise2(); cout << "flap2" << endl; }
};
class Tweety: public Canary {
public:
void noise() { cout << "tweet" << endl; }
void move() { noise(); cout << "run" << endl; }
void noise2() { cout << "tweet2" << endl; }
void move2() { noise2(); cout << "run2" << endl; }
};
int main() {
Canary *yellow = new Tweety();
yellow->noise();
yellow->move();
yellow->noise2();
yellow->move2();
return 0;
}
/* OUTPUT:
tweet <- virtual dispatch
tweet <- virtual dispatch, via Bird::move()
flap <- direct call
chirp2 <- direct call
tweet2 <- direct call, from Tweety::move2()
run2 <- virtual dispatch
*/
#包括
使用名称空间std;
班鸟{
公众:
virtual void noise(){cout此示例没有多重继承。要取消对该行为的支持,您需要了解虚拟成员函数和非虚拟成员函数之间的区别。您在金丝雀
指针上调用移动
,而移动
在金丝雀
上不是虚拟的。我不知道小鸟“咕哝”的声音一个好的C++书应该解释一下。得到一个例子!这个例子没有多重继承。为了理解你需要理解虚拟和非虚拟成员函数之间的区别,你在代码< <代码> >代码> <代码>指针下调用<代码>移动< /COD>不是在<代码>金丝> <代码>上的虚拟。我不知道BIR。一个好的C++书应该解释一下。得到一个!1。次要的东西:我会用“编译器解决”来代替“编译器可以解决”。-因为这不是可选的,而是必需的行为。跟进/澄清问题:如果黄色是金丝雀,那么为什么虚拟函数move不调用move的金丝雀实现?您是说指针类型决定了非虚拟函数的实现,但指针指向的是什么决定了虚拟函数的实现d这是因为virtual如何与编译器一起工作,即您所称的动态调度?@Jack-yellow
具有静态类型Canary
。因为您通过指针调用,所以多态性将应用于您调用的任何虚拟函数。noise
是一个虚拟函数,因此它解析为中的实现ode>Tweety
这就是yellow
所指向的。move
不是虚拟的,所以它是静态解析的。这意味着编译器会查看yellow
的静态类型(aCanary
)并调用Canary
中的move
函数。如果希望在运行时动态解析,则必须将move
设置为虚拟。+1.小问题:我将“编译器可以解析”替换为“编译器确实解析”-因为这不是可选的,而是必需的行为。跟进/澄清问题:如果黄色是金丝雀,那么为什么虚拟函数move不调用move的金丝雀实现?您是说指针类型决定了非虚拟函数的实现,但指针指向的是什么决定了虚拟函数的实现d这是因为virtual如何与编译器一起工作,即您所称的动态调度?@Jack-yellow
具有静态类型Canary
。因为您通过指针调用,所以多态性将应用于您调用的任何虚拟函数。noise
是一个虚拟函数,因此它解析为中的实现ode>Tweety
这就是yellow
所指向的。move
不是虚拟的,所以它是静态解析的。这意味着编译器会查看yellow
的静态类型(aCanary
)并调用Canary
中的move
函数。如果希望在运行时动态解析,则必须将move
设置为虚拟。