是否有语法来防止 class 的实例成为常量?

Is there syntax to prevent instances of a class being const?

假设我创建了一个 class,其中主要用例将让用户始终调用修改其成员的方法。或者,从另一个角度来看,创建一个 class,其中每个方法都会修改一个 class 成员。

例如,让我们使用这个虚拟对象 class:

class Foo
{
public:
    void setM_1(int);
    void setM_2(char);
    void setM_3(float);

private:
    int     m_1;
    char    m_2;
    float   m_3;
};

对于这个 Foo class,创建它的 const 实例没有意义,因为每个方法都保证修改一个成员。

我的目标是:定义此 class 时 const-ly 实例化此 class 不会有任何效果。也就是说,const Foo 实例可以调用 Foo 实例可以调用的所有方法。

我能够通过标记每个方法 const、声明所有非 const 成员 mutable 并提供初始化 class。

所以 const-无知版本的 Foo 看起来像:

class Foo
{
public:
    Foo()
    {
        m_1 = 0;
        m_2 = '[=12=]';
        m_3 = 0.0f;
    }

    void setM_1(int)   const;
    void setM_2(char)  const;
    void setM_3(float) const;

private:
    mutable int     m_1;
    mutable char    m_2;
    mutable float   m_3;
};

我的问题是:有没有更优雅的方法来做到这一点?

或者,这只是糟糕的 class 设计吗? (请不要辩论)。

答案编辑后:
这是官方的:我只是胡扯了脑筋。

Kerrek SB 是对的:创建 const Foo 并使用 class 修改方法无论如何都会引发编译器错误,所以我的“const-无知”Foo 毫无意义。

一点文档就能解决我的 "problem"。

难怪我有一种预感,这是糟糕的 class 设计。

请问大家,这个问题一定很碍眼。感谢您的建设性批评。

您的目标根本不正确。 const 的存在不是为了好玩,而是因为它意味着你真的需要 const。这样的 class 会严重崩溃,例如设置键 - 改变它会破坏排序。还有其他陷阱,例如在某些情况下将其作为临时提供时会发生什么。

如果您的 class 不能以 const 的方式实际使用,界面不应该对此撒谎并假装它是 const 而不是。

关于你关于糟糕设计的问题,我可以肯定地说是的,这听起来像是一个非常糟糕的设计。

不,谢谢 frak。

这毫无意义,而且会非常 confusing/dangerous。

如果您认为 const T 没有意义,那么请不要实例化 const T

从语言的角度,如果aclass不能是const会发生什么不好的事情:

首先,是不允许为其声明const类型的左值,还是禁止对它的const引用?

如果你没有常量引用,那么你将没有默认的复制构造函数或复制赋值运算符。你也不能让 class 成为任何其他 class 的成员,除非它也不能是常量。

我看到一些(草率的)代码,人们在其中实现迭代器,因为他们厌倦了编写样板,他们通过 const_casting 去掉 const 并使用非 const 迭代器来实现 const_iterators执行。他们使用 classes 执行此操作,他们知道不会 "actually" 是常量,因此在他们的程序中不会是未定义的行为。不过,对于维护者来说,可能并没有多少乐趣。

对于这些 classes,class "cannot be const" 从某种意义上说,如果您实际上在堆栈上创建了一个 const 并正常使用它,您在技术上可以获得 UB。

如果您希望编译器在有人创建某些 class 的 const 实例时抱怨,我认为这没有任何意义。 Const 本质上是一个 "promise not to change something"。你为什么要禁止程序员承诺他将如何使用某些东西,这似乎只是有益的。