C ++将对象从另一个类传递到另一个对象

时间:2020-11-05 23:38:35

标签: c++

我正在尝试使用基类和派生类编写此程序,其中有一辆最大载重量为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类而不是Cargo类中的getAmount函数,但是这没有发生。输出应为:

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)的行中进行任何更改。

2 个答案:

答案 0 :(得分:2)

首先,您需要将.on函数设为虚拟:

getAmount()

然后,您的派生类将使用其版本覆盖class Cargo{ public: double c = 0; virtual double getAmount(){ return c; } }; 函数。

如果没有getAmount()关键字,则您的函数接受类型为virtual的参数,它将仅使用Cargo函数。

第二,您需要通过const-reference将对象传递给它,如下所示:

Cargo::getAmount()

这将确保class Truck { double maxCapacity = 8; public: void loadCargo(const Cargo& cargo){ maxCapacity = maxCapacity - cargo.getAmount(); } ... 函数内的cargo对象将引用loadCargo对象或Apple对象。通过传递值,您将Kiwi对象复制到Apples对象中,并且掉到了slicing problem上。

ETA:您还需要像下面这样将Cargo函数更改为getAmount()

const

由于您提到无法更改Truck类,因此可以通过在Cargo类构造函数中设置// vvvvv double getAmount() const { return c; } 的值来实现。像这样:

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. }; getAmount()类中删除Apple函数(但对于Kiwi类保留KEEP)。

最终通知

请记住,按值传递货物将始终遭受切片问题(请参见上面的链接),因此应避免使用,尽管因为您的CargoApple对象没有任何成员变量,它将仍然适用于您的分配。如果您的老师希望继承是这样工作的,那么按值将Kiwi传递到Cargo不好的C ++实践。这不会影响您的分配,但是如果您希望认真对待C ++,请记住这一点,以备将来之需!

答案 1 :(得分:1)

拨打电话时:

truck.loadCargo(Apple());

您的确将Apple传递给truck。但是,loadCargo的声明带有一个Cargo对象:

void loadCargo(Cargo cargo)

这将切片Apple,现在您只需拥有一个调用Cargo的{​​{1}}对象。这将返回0,因此getAmount不变。

有多种解决方法,但是最简单的方法是将maxCapacity用作模板,以便它可以接受任何类型而无需先将其转换为loadCargo对象:

Cargo

这里是demo


请注意,对于此实现,只要template<typename Fruit> void loadCargo(Fruit cargo) Apple具有与Kiwi对象相同的成员函数,就可以避免完全从基类继承。 / p>