繁体   English   中英

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

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

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

    // getAmount() function removed.
};

最后,从您的AppleKiwi类中删除getAmount()函数(但对于Cargo类,请保留 KEEP)。

最后说明

请记住,按值传递 Cargo 总是会遇到切片问题(见上面的链接),应该避免,尽管因为您的AppleKiwi对象没有任何成员变量,它仍然适用于您的分配。 如果您的讲师希望继承是如何工作的,那么将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)

这是一个演示


请注意,对于此实现,只要AppleKiwi具有与Cargo对象预期相同的成员函数,就可以完全避免从基类继承。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM