是否存在防止类的实例为const的语法
Is there syntax to prevent instances of a class being const?
假设我创建了一个类,其中主要用例将使用户始终调用修改其成员的方法。或者,从另一个角度来看,创建一个类,其中每个方法都将修改一个(多个)类成员。
例如,让我们使用这个虚拟类:
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来实现这种行为。
所以Foo
的const
-无知版本看起来像:
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本质上是"不改变某事的承诺"。为什么你要禁止程序员做出关于他将如何使用某些东西的承诺,这似乎只是有益的。
- muQueue.front() 给出了 const 实例,即使我没有将其标记为 const
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在字符串函数中抛出'char const*'实例后调用的终止
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- 是否允许使用初始值设定项列表将const数组引用实例化为构造函数参数
- 自定义链表const_iterator无法遍历列表的非const实例
- 引发"char const*"错误的实例后调用的终止
- 无法用const char *数组实例化模板
- C++:具有 const int 的类的 vector.erase 实例给出"attempting to reference a deleted function"错误 C2280
- 为什么将FMTFLAG指定两次 - 作为枚举的一部分,而另一个实例为静态const变量
- 如何处理 const T& 和 T&& 实例化到同一个签名?
- 我可以在类头文件中定义一个类的const静态实例吗
- 当丢失非const虚拟方法时,为什么我不能实例化类的const实例
- 当此实例为const时,请引发异常
- 复制MyGreatClass的const*实例的正确方法
- 自定义类的const实例化是否也会使类中的*everything*变为常量
- 为什么无法使用复制构造函数实例化"non const"而可以在没有复制构造函数的情况下实例化配对?
- 为什么我不能在复制构造函数中更改实例的私有数据,如果它是 const 的?
- 通用成员函数定义,可从 'const' 和 'non-const' 对象实例化
- 为什么用const char*变量构造类的未分配临时实例是错误的,而该类具有const char*constructor