![](/img/trans.png)
[英]Passing object from another class to a constructor of the other in C++?
[英]C++ Passing an Object to Another Object From Another Class
我正在尝试使用基类和派生类编写这个程序,其中有一辆最大容量为 8 吨的卡车。 然后这辆卡车装载1.5吨苹果,然后装载0.5吨猕猴桃。 这将在装载苹果时将剩余吨数减少到 6.5 吨,然后在装载猕猴桃时减少到 6 吨。 这是一个分配,在主函数中我看到他们正在调用函数loadCargo
如下truck.loadCargo(Apple())
,我不确定这是完成了什么。 请看一下完整的代码:
#include <iostream>
#include <string>
using namespace std;
class Cargo{
public:
double c = 0;
double getAmount(){
return c;
}
};
class Apple : public Cargo{
public:
double c = 1.5;
double getAmount(){
return c;
}
};
class Kiwi : public Cargo{
public:
double c = 0.5;
double getAmount(){
return c;
}
};
class Truck {
double maxCapacity = 8;
public:
void loadCargo(Cargo cargo){
maxCapacity = maxCapacity - cargo.getAmount();
}
void printInfo(){
cout << maxCapacity << " tons remaining" << endl;
}
};
int main() {
Truck truck;
truck.printInfo();
truck.loadCargo(Apple());
truck.printInfo();
truck.loadCargo(Kiwi());
truck.printInfo();
}
我认为truck.loadCargo(Apple())
会将 Apple 的对象传递给对象货物。 因此,当loadCargo
被调用时,它将访问 Apple 类中的getAmount
函数,而不是 Cargo 类中的函数,但这并没有发生。 输出应该是:
8 tons remaining
6.5 tons remaining
6 tons remaining
但目前它是以下内容,因为它只使用 Cargo 类中的getAmount
:
8 tons remaining
8 tons remaining
8 tons remaining
编辑:由于这是一项分配,我无法更改主函数或具有void loadCargo(Cargo cargo)
的行中的任何内容。
首先,您需要将getAmount()
函数getAmount()
虚拟:
class Cargo{
public:
double c = 0;
virtual double getAmount(){
return c;
}
};
然后,您的派生类将使用它们的版本覆盖getAmount()
函数。
如果没有virtual
关键字,如果您的函数接受Cargo
类型的参数,它将只使用Cargo::getAmount()
函数。
其次,您需要通过常量引用将对象传递给,如下所示:
class Truck {
double maxCapacity = 8;
public:
void loadCargo(const Cargo& cargo){
maxCapacity = maxCapacity - cargo.getAmount();
}
...
这将确保loadCargo
函数内的cargo
对象将引用Apple
对象或Kiwi
对象。 通过按值传递,您将Apples
对象复制到Cargo
对象中,并且您会遇到切片问题。
ETA:您还需要像这样将getAmount()
函数更改为const
:
// vvvvv
double getAmount() const {
return c;
}
既然你提到你不能改变你的 Truck class ,你可以通过在 Cargo 类构造函数中设置c
的值来做到这一点。 像这样:
class Cargo{
public:
double c;
// Constructor, using an initializer list to set the value of `c`.
Cargo(const double c_value) :
c(c_value) {
}
double getAmount(){
return c;
}
};
然后,在您的Apple
和Kiwi
类中,在构造函数中设置c
的值,如下所示:
class Apple : public Cargo{
public:
// Set the Cargo's mass in the Apple constructor...
Apple() :
Cargo(1.5) {
}
// getAmount() function removed.
};
最后,从您的Apple
和Kiwi
类中删除getAmount()
函数(但对于Cargo
类,请保留 KEEP)。
最后说明
请记住,按值传递 Cargo 总是会遇到切片问题(见上面的链接),应该避免,尽管因为您的Apple
和Kiwi
对象没有任何成员变量,它仍然适用于您的分配。 如果您的讲师希望继承是如何工作的,那么将Cargo
按值传递给loadCargo(Cargo cargo)
是不好的 C++ 实践。 这不会影响您的作业,但如果您想认真对待 C++,请记住这一点,以备将来使用!
当您拨打此电话时:
truck.loadCargo(Apple());
您确实是将Apple
传递给了truck
。 然而, loadCargo
的声明需要一个Cargo
对象:
void loadCargo(Cargo cargo)
这对Apple
切片,现在您只有一个Cargo
对象,您getAmount
在其上调用getAmount
。 这将返回 0,因此maxCapacity
不会改变。
有多种方法可以解决这个问题,但最简单的方法是使loadCargo
成为一个模板,这样它就可以接受任何类型,而无需先将其转换为Cargo
对象:
template<typename Fruit>
void loadCargo(Fruit cargo)
这是一个演示。
请注意,对于此实现,只要Apple
和Kiwi
具有与Cargo
对象预期相同的成员函数,就可以完全避免从基类继承。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.