【问题标题】:In C++, is there a way I can make a mutable const member variable? Like with the "final" keyword in java?在 C++ 中,有没有办法可以制作一个可变的 const 成员变量?就像java中的“final”关键字一样?
【发布时间】:2020-12-13 21:48:56
【问题描述】:

我正在创建一个游戏引擎类,它将有一个“记录器”成员。 像这样:

class Engine {
public:
    const Logger logger;
    Engine();
    ~Engine();

    void init();
    void start();
};

我的问题是是否可以制作“记录器”,这样我就不能覆盖变量,但仍要修改对象本身?

【问题讨论】:

  • C++ 中没有变量覆盖这样的东西。不清楚你想要什么。
  • 似乎在java中=具有“覆盖”(如您所说)对象的特殊含义。但在 C++ 中,它没有任何特殊含义。对于类,它只是一个成员函数,它遍历每个字段并为它们分配新值。因此,创建一个对象const 会禁用分配,就像它禁用任何可以修改成员的成员函数一样。
  • 我不明白。你想修改它,但你不想修改它。您希望它是 const,但您希望它是可变的。嗯!
  • 在 Java 中,您的类对象是语法更漂亮的指针。
  • @AsteroidsWithWings 我希望能够修改它的成员并调用非常量方法,同时不允许另一个实例通过分配来替换它。我的想法是覆盖分配运算符,但这似乎不合逻辑。如果您想更好地理解我的意思,请查看 final 关键字在 java 中的作用。

标签: java c++ constants overriding final


【解决方案1】:

您提出的问题在 C++ 中没有意义。考虑一下:

class A {
  public:
    int x;
};

A a1, a2;
a1.x = 1;
a2.x = 2;

现在,我们可以通过赋值给a1a2 相同的值:

a1 = a2;

或者我们可以简单地将a1的状态替换为a2的状态,一次一个:

a1.x = a2.x;

这两个语句具有相同的效果。它们都原地覆盖a1 的状态。

所以不,没有“final”关键字仅禁用对成员的一些覆盖操作(即分配),同时允许其他覆盖操作。

在Java 中,final 关键字防止变量被重新分配以引用另一个实例,但允许修改现有实例。在 C++ 中,赋值永远不会改变实例的标识,因此不需要类似的关键字。

【讨论】:

    【解决方案2】:

    C++ 首先没有“替换”变量的概念,所以你要求的东西没有多大意义。写C++的时候最好忘记Java;它们是具有不同范式和概念的不同语言。

    如果您想阻止您的类的用户能够在逻辑上“替换”它,那么与 C++ 中最接近的是 = 运算符。这实际上只是在现有对象上调用 operator= 函数,尽管传统上我们通常实现该函数以将状态从一个复制到另一个,因此从非常高级的角度来看,可以考虑类似的东西。

    如果您不希望人们这样做,请将 operator= 设置为 deleted(或 private)在 Logger 中。现在连想象中的能够“取代”它的概念都没有。保持其实例非const 并且所有其他用法仍然可以访问。

    如果有帮助,请想象您的类Engine 不包含Logger,而是一个指向某个动态分配对象的Logger*。如果它是Logger* const,那么指针将不允许稍后指向其他地方,尽管指针对象(Logger 本身)将保持可变。这是最接近 Java 的引用语义和 final 的东西,我可以为这个示例收集。 然而我警告不要进行不必要的动态分配:仅将此选项用于心理比较!

    【讨论】:

    • 是否建议使用重新调整 const 引用的 getter?人们是否曾经这样做过,或者人们通常不太关心这个问题?
    • 在不了解您的项目或目标的情况下(不,“不要让人们修改 Logger”不算作目标;这是您的实施决策之一)我真的不能在这里说什么是合适的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 2016-09-06
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    相关资源
    最近更新 更多