【问题标题】:can't call a function for a class member不能为类成员调用函数
【发布时间】:2020-10-11 12:02:39
【问题描述】:

在下面的例子中,为什么我不能调用 car.getFuelConsumption

class Road {
public:
    double length(); // km
    int speed(); // km per hour ;
};

class Car {
protected:
    virtual double getFuelConsumption(int speed_in_km) = 0;
};

class Tank: public Car{
public:
    double getFuelConsumption(int speed_in_km) {
        return 1;
    }
};

double getPetrol(std::vector<Road> roads, const Car &car) {
    double total_fuel_consumption=0;
    for (int i=0;i<roads.size();++i)
    {
        double fuel_consumption_per_road = car.getFuelConsumption(roads[i].speed());
    }
    return total_fuel_consumption;
}

每辆车都有这样的方法,为什么我不能调用它?例如,如果我将 Tank 发送到 getPetrol(),那么我希望它能够正常工作并调用 Tank 版本的 getFuelConsumption()


Undefined symbols for architecture x86_64:   "Road::speed()", referenced from:
getPetrol(std::__1::vector<Road, std::__1::allocator<Road> >, Car const&) 
in main.cpp.o ld: symbol(s) not found for architecture
x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

【问题讨论】:

  • car.getFuelConsumption 不是调用函数的方式。做例如total_fuel_consumption += car.getFuelConsumption(some_speed_value); 是调用函数并使用其返回值的方式。
  • 尝试了解动态与静态绑定。
  • 我知道,但我只是想举个简单的例子
  • 如果您遇到构建错误,您应该同时包含导致错误的minimal reproducible example 以及实际错误本身(复制粘贴为文本,完整且完整),并cmets 在出现错误的行上。也请花一些时间阅读How to Ask,以及this question checklist
  • 该错误表明Road::speed 函数不存在(它未定义,即未实现)。它是否在您忘记包含在项目中或忘记构建的其他源文件中实现?

标签: c++ class methods runtime-error


【解决方案1】:

您的代码的明显问题如下:

  • getPetrol()是在类外定义的,它调用了一个受保护的成员getFuelConsumption(),受保护的成员不能在类外调用。

    要修复它,您需要在基类中创建 getFuelConsumption() public 方法。

  • 因为你有一个const对象参数const Car &amp;car,方法getFuelConsumption()需要有const返回,const对象不能调用非常量方法。您也可以从 car 参数中删除 const 关键字,但在这种情况下第一个选项就足够了。

  • 由于您将使用抽象基类对派生类的引用,实际上是多态性,因此还建议使用虚拟析构函数,但会受到调用未定义行为的惩罚。

  • 您提到的链接器错误可能是因为 Road 方法已声明但未定义,至少在您显示的代码中没有。

更正的代码:

Live demo

#include <iostream>
#include <vector>

class Road {
public:
    double length(){ return 0;} // added function body to avoid linker error
    int speed(){ return 0; }    // ""  
};

class Car {
public:
    virtual double getFuelConsumption(int speed_in_km) const = 0;
    virtual ~Car(){} //virtual destructor
};

class Tank : public Car {
public:
    double getFuelConsumption(int speed_in_km) const {
        return speed_in_km;
    }
};

double getPetrol(std::vector<Road> roads, const Car &car) {
    double total_fuel_consumption = 0;
    for (size_t i = 0; i < roads.size(); ++i) {
        total_fuel_consumption += car.getFuelConsumption(roads[i].speed());
    }
    return total_fuel_consumption;
}

【讨论】:

    【解决方案2】:

    汽车是const,但方法不是const。您不能在 const 对象上调用非常量方法。见https://www.learncpp.com/cpp-tutorial/810-const-class-objects-and-member-functions/

    【讨论】:

    • 如果我写:“doublefuel_consumption_per_road = car.getFuelConsumption(roads[i].speed());”我收到链接器错误
    • 有可能,取决于您链接的内容。例如,道路不是您的源代码的一部分...
    • 这方面有什么帮助吗?
    • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
    • 我相信这是他为什么不能调用该方法的问题的答案。您不能在 const 对象上调用非常量方法。对问题进行了编辑并添加了第二部分。
    猜你喜欢
    • 2020-01-23
    • 1970-01-01
    • 2021-09-02
    • 2011-06-04
    • 2020-12-04
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多