首页 > 解决方案 > 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 的对象传递给对象 cargo。因此,当loadCargo被调用时,它将访问getAmountApple 类中的函数,而不是 Cargo 类中的函数,但这并没有发生。输出应该是:

8 tons remaining
6.5 tons remaining
6 tons remaining

但目前它是以下内容,因为它只是使用getAmountCargo 类中的:

8 tons remaining
8 tons remaining
8 tons remaining

编辑:由于这是一项任务,我无法更改主函数或具有void loadCargo(Cargo cargo).

标签: c++

解决方案


首先,您需要使您的getAmount()功能虚拟:

class Cargo{
public:
    double c = 0;
    virtual double getAmount(){
        return c;
    }
};

getAmount()然后,您的派生类将使用其版本覆盖该函数。

如果没有virtual关键字,如果您的函数接受 type 的参数Cargo,它将只使用该Cargo::getAmount()函数。

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

class Truck {
    double maxCapacity = 8;
public:
    void loadCargo(const Cargo& cargo){
        maxCapacity = maxCapacity - cargo.getAmount();
    }
    ...

这将确保您在函数cargo内的对象loadCargo将引用一个Apple对象或Kiwi对象。通过按值传递,您将Apples对象复制到Cargo对象中,并且您遇到了切片问题

ETA:您还需要将您的getAmount()功能更改为const

//                 vvvvv
double getAmount() const {
    return c;
}

既然你提到你不能改变你的 Truck 类c,你可以通过在 Cargo 类构造函数中设置的值来做到这一点。像这样:

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;
    }
};

然后,在您的AppleKiwi类中,设置c构造函数内部的值,如下所示:

class Apple : public Cargo{
public:
    // Set the Cargo's mass in the Apple constructor...
    Apple() :
        Cargo(1.5) {
    }

    // getAmount() function removed.
};

最后,从你的和类中删除getAmount()函数(但为类保留)。AppleKiwiCargo

最后说明

请记住,按值传递 Cargo 总是会遇到切片问题(参见上面的链接)并且应该避免,尽管因为您的AppleKiwi对象没有任何成员变量,它仍然适用于您的分配。如果继承是您的讲师希望它工作的方式,那么Cargo按值传递loadCargo(Cargo cargo)不好的 C++ 实践。这不会影响您的作业,但如果您想认真对待 C++,请记住这一点!


推荐阅读