是否有语法来防止 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"。你为什么要禁止程序员承诺他将如何使用某些东西,这似乎只是有益的。
假设我创建了一个 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"。你为什么要禁止程序员承诺他将如何使用某些东西,这似乎只是有益的。