是否存在防止类的实例为const的语法

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

本文关键字:实例 const 语法 存在 是否      更新时间:2023-10-16

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

例如,让我们使用这个虚拟类:

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类,创建它的const实例是没有意义的,因为每个方法都保证修改一个成员。

我的目标是:以这样一种方式定义这个类,即const -ly实例化这个类不会产生任何影响。也就是说,const Foo实例可以调用Foo实例可以调用的所有方法。

我能够通过标记每个方法const,声明所有非const成员mutable,并提供一个初始化类所有成员的actor来实现这种行为。

所以Fooconst -无知版本看起来像:

class Foo
{
public:
    Foo()
    {
        m_1 = 0;
        m_2 = '';
        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;
};

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

或者,这只是糟糕的类设计?(请不要争论)。

回答后编辑:
官方消息:我刚拉了个脑屎。

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

一个小文档将解决我的"问题"。

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

对不起,各位,这个问题一定很碍眼。谢谢你的建设性意见。

你的目标根本不正确。const的存在不是为了好玩,而是因为它意味着你真的需要const。这样的类会像set键那样严重地中断,在set键中,改变它会破坏顺序。还有其他一些缺陷,比如在某些情况下将其作为临时对象提供时会发生什么。

如果你的类不能以const的方式实际使用,接口不应该撒谎,假装它不是const

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

不用了,谢谢。

这没有意义,而且会非常混乱/危险。

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

从语言的角度来看,如果一个类不能为const,会发生什么糟糕的事情:

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

如果没有const引用,则没有默认复制构造函数或复制赋值操作符。也不能让类成为其他类的成员,除非它也不能是const。

我见过一些实现迭代器的(草率的)代码,因为他们厌倦了编写样板文件,他们通过const_cast去掉const并使用非const迭代器实现来实现const_iterator。他们这样做的类,他们知道不会"实际上"是const,所以它不会是未定义的行为在他们的程序。但是,对于维护人员来说,这可能不是很有趣。

对于这些类,类"不能是const",因为如果你在堆栈上创建了一个const类,并正常使用它,从技术上讲,你可以得到UB。

如果你想让编译器在某人创建某个类的const实例时报错,我认为这是没有意义的。Const本质上是"不改变某事的承诺"。为什么你要禁止程序员做出关于他将如何使用某些东西的承诺,这似乎只是有益的。

相关文章: