派生虚函数返回奇怪的结果
C++: Derived virtual function is returning strange results
我在. hpp文件中创建了一个带有虚函数的可衍生类,然后在类的. cpp文件中给它一个默认返回值。接下来,我创建了一个类,它继承了后一个可派生类,并重载了它的虚函数,给它一个新的返回值。然而,返回值并不总是相同的(要么是默认返回值,要么是重载返回值)。有人能帮我修复我的代码或找到问题。谢谢。
注意:我提供了示例代码,我相信它足以显示问题。
#include <iostream>
#include <sstream>
using std::cout;
using std::ostream;
class Fruit;
class Apple;
class Fruit
{
public:
int Type;
Fruit();
~Fruit();
Fruit(int = 0);
virtual const int getVal() const;
};
class Apple : public Fruit
{
public:
Apple();
~Apple();
const int getVal() const;
};
Fruit::Fruit() : Type(0) {}
Fruit::~Fruit() {}
Fruit::Fruit(int type) : Type(type) {}
//const int Fruit::getVal() const { return 0; } //Uncommenting this results in function //always returning ZERO; even in Apple::getVal().
const int Fruit::getVal() const { return Type; }
Apple::Apple() : Fruit(1) {}
Apple::~Apple() {}
const int Apple::getVal() const { return Type; }
ostream& operator<<(ostream& a, Fruit b)
{
return a << b.getVal();
}
int main(int *argc, char **argv)
{
cout << Apple() << "nn";
#ifdef _WIN32
system("pause");
#endif
return 0;
}
你遇到了一个被称为对象切片的问题。因为你的Apple
是按值传递给你的operator<<
,只有对象的Fruit
部分被复制。因此,当getVal
被调用时,它是在基类Fruit
上调用的,而不是在您的Apple
上。
要解决这个问题,请确保在处理基类时使用引用(或指针)而不是值。例如,这里的修复是简单地采用const Fruit&
而不仅仅是Fruit
。
ostream& operator<<(ostream& a, const Fruit& b)
{
return a << b.getVal();
}
正如维基百科条目所说,这个问题在c++中突然出现,因为"按值赋值不是多态的"。
ostream& operator<<(ostream& a, Fruit b)
这段代码使用定义为Fruit(const Fruit&);
的构造函数构造了一个Fruit类型的新对象。
Apple
是Fruit
,所以它可以用作Fruit复制构造函数的参数,然而,Fruit
复制构造函数生成一个常规的Fruit
,而不管你提供的Fruit的子类是什么,因此你只会得到一个常规的Fruit
。这被称为"切片",有些令人困惑。
ostream& operator<<(ostream& a, const Fruit& b)
我还建议在fruit类的私有部分(未实现)声明复制构造函数和赋值操作符,这样您就不会再意外地犯这个错误了
您遇到了切片问题。您的operator<<
正在获取对象的副本,而不是对它的引用。由于您没有定义复制构造函数,编译器为您定义了一个,并且它正在做错误的事情。
很快跳出来的一件事是,您没有通过指针调用getVal(),并且由于您的operator<<
接受的是Fruit而不是Apple,因此它有效地切掉了对象的派生部分。请尝试将Fruit&
作为operator<<
的参数。
修改如下:ostream& operator<<(ostream& a, Fruit b)
{
return a << b.getVal();
}
:ostream& operator<<(ostream& a, const Fruit& b)
{
return a << b.getVal();
}
它应该可以工作。
在你的实现中,你正在从Apple构造一个全新的Fruit实例。调用Fruit::getVal()
- 如何返回一个类的两个对象相加的结果
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- C++Brute Force攻击函数不会返回结果
- 如何从递归函数中完全返回,该函数给出了每个函数结果的累积相加?
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 为什么我的程序在 O0 和 O2 的优化级别返回不同的结果
- c++ lambda:柯里和函数:使用按值捕获与按引用捕获返回不同的结果
- C++ 获取函数在常量引用中按值返回的结果
- 如何在一个表达式中生成并返回结果?
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- 三元运算符在返回语句中给出意外的结果
- 为什么函数 tellg() 没有返回好的结果?
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 有没有办法将 for 循环结果返回到像三元运算符这样的函数中?
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- 检查文本文件中的 0 或 1,并根据结果返回
- 如何使用boost::any_range连接多个boost范围并作为函数w/o的结果返回
- 如何从线程的结果返回Qt对象(Qtfutur)
- C++:当在函数内部创建新对象并将其作为结果返回时,我必须使用新运算符来创建对象