调用常量引用的基成员方法?

Call base member method of constant reference?

我的class结构是这样的:

class Simulationobject {
protected:
    std::string p_sName;
public:
    const std::string sGetName();
};

class Lane : Simulationobject {
    //Some irrelevant functions and variables
};

class Vehicle : Simulationobject{
public:
    const virtual void vDraw(const Lane& lane);
};

class Car : Vehicle {
public:
    const void vDraw(const Lane& lane) override;
};

我现在想在 Vehicle 的 vDraw 中调用外部库中的函数。它接受一个字符串作为参数bool externFunction(std::string str);。该库无权访问 classes 和我项目的成员,只是发送一些 TCP 请求,效果很好。我的问题是 vs 不允许我用 lane.sGetName() 这样做。 std::string str = lane.sGetName() 也不起作用,因此调用 sGetName() 无效。

const void Car::vDraw(const Lane& lane) {
    externFunction(lane.sGetName());
}

现在,我知道您不能从常量引用调用非常量函数。但是 sGetName() 是常数,不是吗?

我错过了什么吗?帮助将不胜感激!作为一个快速而肮脏的修复,我将 vDraw 设为一个非常量函数。但是我想保持我的代码完整。

感谢您的帮助!

const std::string sGetName(); 是一个非常量函数,它 return 是一个常量字符串。

函数本身不是常量。它只是 return 一个常量对象,但作为 Simulationobject 的成员函数,它可以修改 this.

您可能想要的是: const std::string sGetName() const;

const函数名告诉编译器该函数不会修改this。 IOW:调用 object.sGetName() 不会修改 object 本身。

所以现在,

const void Car::vDraw(const Lane& lane) {
    externFunction(lane.sGetName());
}

应该可以。 lane 是常量对象。 sGetName 承诺它不会改变它所调用的对象。所以 lane.sGetName() 是有效的。

这一切之所以成为可能,是因为 const 这个名字。

==== 现在关于名称前的常量:

您声明 sGetName()

const std::string sGetName() (const)

这意味着,该函数将return一个临时的std::string对象,即const。

您可能想要的是:

const std::string &sGetName() const
{
   return p_sName;
}

在这里你 return 引用一个成员变量以避免复制字符串。必须复制上面的临时对象。

但是如果你想阻止调用者修改你的 p_sName.

,你不能 return 对成员的引用

所以你 return 一个 const 引用代替:

const std::string&...

return是对成员变量的常量引用。

==> 无需复制,但没有人可以更改成员变量。调用者只能读取成员变量的值 ==> 因此 sGetName 仍然是一个 const 函数。

如果您想调用 sGetName(),您需要更改 Lane 的 class 声明以公开继承自 SimulatonObject。此外,您需要将 sGetName() 设为 const(如果是)。

class Simulationobject {
protected:
    std::string p_sName;
public:
    std::string sGetName() const;
    // or const std::string& sGetName() const; // this probably better, ymmv
};

// make inheritance PUBLIC!!! otherwise, sGetName hidden
class Lane : public Simulationobject {
    //Some irrelevant functions and variables
};