c++ 最终常量字符串
Posted
技术标签:
【中文标题】c++ 最终常量字符串【英文标题】:c++ Final constant strings 【发布时间】:2010-12-08 20:45:00 【问题描述】:在 Java 中,我们可以指定一个字符串为final
来声明“常量”。例如
static final String myConst = "Hello";
这样在 c++ 中执行此操作的正确方法是这样吗?
const char * const myConst = "Hello";
我总是看到人们这样做:
const char * myConst = "Hello";
但是,实际上,您可以更改该指针指向的内容。那么,为什么人们不将指针也声明为常量呢?正确的做法是什么?
【问题讨论】:
不,您不能更改指针指向的内容。你可以改变指针。 仅供参考,在 C++ 中,您应该向后阅读。const char * myConst
读作:“myConst 是一个指向常量字符的指针”。 const char * const myConst
被读作“myConst 是一个指向常量字符的常量指针”。
大多数时候你看到最后一个选项,写声明的人根本不知道。
@Alexandre C. 是的,这就是我的意思。我输入的内容有些模棱两可。 “更改指针指向的内容”就像更改指针值,而不是更改字符串。
【参考方案1】:
const std::string myConst("Hello");
【讨论】:
不要忘记静态部分。要镜像 Java,它需要是一个静态成员变量(尽管我认为 global 很好),因为它可能具有问题尚未明确的访问限制。 @Martin:好吧,如果它是静态成员,它也不能在声明中初始化。【参考方案2】:是的,const char* const
是声明您不会更改的 C 样式字符串的正确方法。
或者更好:
#include <string>
const std::string myConst = "Hello";
【讨论】:
【参考方案3】:const char * myConst = "Hello";
这意味着指向的对象不能改变。
char * const myConst = "Hello";
这意味着指针指向的位置不能改变,但对象的值可以。
const char * const myConst = "Hello";
这意味着两者都不会改变。根据我的经验,没有人记得这一点,但它总是可以在网上找到!
典型的,三个人在我写我的时候回答!
【讨论】:
@kriss 我认为在 C++ 中存在从字符串文字到char*
的隐式转换,以便向后兼容 C。
@kriss:如果你的编译器是合理的,第二个会导致编译器警告,但如果你的编译器是兼容的,则不会导致错误,因为马克说的原因它是合法的 C++。
没关系,这更有教育意义:char * const myConst = "H";
@Mark @Steve:好的警告,只有像我这样的偏执型将 -Werror 设置为默认值 ;-)
@cbamber85:这个是允许的,不会静默编译器(因为你仍然可以更改字符串指针)。【参考方案4】:
我不太明白你的问题。为了或多或少模仿final
Java 关键字,它可以是
const char * const myConst = "Hello";
(如果指针不会改变),和/或:
const char * myConst = "Hello";
如果指针之后可能会改变。最后,请注意,在第一个版本中,您实际上无法更改指针本身,因为它是常量。
【讨论】:
【参考方案5】:有了 Diego 的编辑,是的,这是正确的编写方式。人们通常不声明变量 const,因为他们不关心它是否会被修改,或者更确切地说,相信它不会被修改(因为他们知道他们不会修改它)。
他们声明指向的 const 是因为字符串文字确实具有 const 字符,因此您确实必须将其分配给具有 char const * 值的变量。
【讨论】:
【参考方案6】:技术上,
char * const myConst = "Hello";
是最正确的答案,因为重新分配指针会留下一个可能无法恢复的字符串。
某些实现允许您更改“Hello”中的字符(即使这是一个坏主意),因此
中的第一个 constchar const * const myConst = "Hello";
是个好主意。个人认为
char const * myConst = ...;
和 const char * myCount = ...;
是等价的,我倾向于强制执行一个样式指南,即 const 始终遵循它修改的项目。从长远来看,它有时会减少误解。
也就是说,大多数人不知道如何在 C++ 中正确使用const
,所以要么使用不好,要么根本不使用。那是因为他们只是使用 C++ 作为改进的 C 编译器。
【讨论】:
char * const myConst = "Hello";这没有定义一个常量 C 字符串。这是 C++ 允许与 C 兼容的一种技巧。您正在将字符串文字分配给指向非常量字符串的指针。当然,每个编译器都必须允许变异操作,例如myConst[2] = 'a';这也是未定义的行为。 @Gene Bushuyev:你为什么说myConst[2] = 'a';
是未定义的行为? 'a'
只是在数字类型 char 中设置值的简写(只是在 ASCII 环境中编写 myConst[2] = 97;
的另一种方式)。为什么在数组中设置 97 会是未定义的行为?【参考方案7】:
但是,实际上,你可以改变什么 那个指针指向。那么,为什么要 人们没有将指针声明为 也恒定?什么是正确的 怎么办?
因为它很少有用,所以您通常希望堆栈上的值(包括指针)是非常量的。获取 Sutter 和 Alexandrescu “编码标准”一书,它解释了这一点。
【讨论】:
【参考方案8】:真正的问题是程序员不得不将一些指针至少声明为const char *
,以便在双引号之间存储字符数组。没有什么能强迫他们(没有编译器警告或错误)也使指针保持不变......因为人们很懒,你可以得出自己的结论。他们可能甚至没有真正尝试定义一个常量,他们只是想关闭编译器错误(好吧,在这种情况下是警告)。
记住这一点,我可能会选择不同的解决方案:
const char myConst[] = "Hello";
这里的不同之处在于,这样我不会将用作字符串的原始字节数组衰减为指针,我仍然会有一个可以完全用作原始文字的字节数组。
有了它,我可以执行sizeof(myConst)
之类的操作,并获得与sizeof("Hello")
相同的结果。如果我将字符串更改为指针,sizeof 将返回指针的大小,而不是字符串的大小...
...显然,当以这种方式做事时,更改指针变得毫无意义,因为不再有指针可以更改。
【讨论】:
以上是关于c++ 最终常量字符串的主要内容,如果未能解决你的问题,请参考以下文章