我正在做一个关于 C++ 继承的家庭作业,但我无法理解为什么我的代码中会发生这种情况。我有一个从 Figure 类派生的 Triangle 类,并且该程序没有按照我期望的方式运行。在 Main.cpp 文件中,创建了一个 Triangle 对象并调用了 draw()
函数,我希望这个函数调用在figure.cpp中定义的函数,但它似乎调用的是在triangle.cpp 中定义。我认为只有使用关键字 virtual
定义函数时才会出现这种情况?
对于分配,我必须找到两种情况下程序的输出:一种是使用关键字virtual
,另一种是不使用关键字virtual
。我的程序现在对于两种情况都有相同的输出。我通过打印出一条语句来显示调用了哪个版本的函数来实现这些函数。我相信这是在派生类中重新定义函数的正确方法。
main.cpp
#include <iostream>
#include "figure.h"
#include "triangle.h"
using std::cout;
int main()
{
Triangle tri;
//This function should invoke the one from figure.cpp
tri.draw();
return 0;
}
图.h
#ifndef _FIGURE_H_
#define _FIGURE_H_
#include <iostream>
class Figure {
public:
Figure();
void draw();
void erase();
void center();
};
#endif
图.cpp
#include "figure.h"
Figure::Figure() {
}
void Figure::draw() {
std::cout << "Calling Figure::draw()" << std::endl;
}
void Figure::erase() {
std::cout << "Calling Figure::erase()" << std::endl;
}
void Figure::center() {
std::cout << "Calling Figure::center()" << std::endl;
}
三角形.h
#ifndef _TRIANGLE_H_
#define _TRIANGLE_H_
#include <iostream>
#include "figure.h"
class Triangle : public Figure {
public:
Triangle();
void draw();
void erase();
void center();
private:
double base;
double height;
double centerPoint;
};
#endif
三角形.cpp
#include "triangle.h"
Triangle::Triangle() {
base = 0.0;
height = 0.0;
centerPoint = 0.0;
}
void Triangle::draw() {
std::cout << "Calling Triangle::draw()" << std::endl;
}
void Triangle::erase() {
std::cout << "Calling Triangle::erase()" << std::endl;
}
void Triangle::center() {
std::cout << "Calling Triangle::center()" << std::endl;
}
*更新
我创建了另一个不使用单独编译的程序,它给了我我所期望的。为什么单独编译会导致不同的结果?下面是我正在测试的代码,它不使用单独编译。在 main 中调用 draw()
会调用图中定义的函数,如果我取消注释函数声明,则会调用 Triangle 中的函数。
#include <iostream>
using namespace std;
class Figure {
public:
Figure() {
}
void draw() {
cout << "Calling Figure::draw()" << endl;
}
};
class Triangle : public Figure {
public:
Triangle() {
}
// void draw() {
// cout << "Calling Triangle::draw()" << endl;
// }
};
int main () {
Triangle tri;
tri.draw();
return 0;
}
最佳答案
Triangle
继承了 Figure
的 draw
函数。
这意味着,如果您从 Triangle
中删除了 void draw();
的声明,您仍然能够调用 tri.draw()
在 main
函数中,它将调用 Figure::draw
。
但是,当您确实在Triangle
内声明void draw();
时,它实际上替换 draw
函数是从 Figure
继承的,这使得您根本就没有从 Figure
继承它。
因此,如果您希望它从 Figure
调用 draw
函数,一种选择是不在 Triangle 中替换它。 p>
另一种选择是让 Triangle::draw
在 Triangle::draw
的函数体内手动调用 Figure::draw
。
关键字virtual
做了一些不同的事情:它允许发生相反的效果。
假设您声明:
Figure & f = tri;
f.draw();
就编译器所知,f
是对图形的引用,并且可以引用任何类型的任何图形。
然而,在这种情况下,如果draw
函数被声明为virtual
,它将允许程序在运行时确定f到底是什么类型的图形。
引用,从而允许程序为任何给定的 Figure
派生类型的引用调用正确版本的 draw
。
关于c++ - 派生类忽略基类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27437036/