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”中的字符(即使这是一个坏主意),因此

中的第一个 const
char 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++ 最终常量字符串的主要内容,如果未能解决你的问题,请参考以下文章

C++ 不推荐将字符串常量转换为 'char*'

常量到非常量 c++

C++ 常量字符

常量字符串如何在 C++ 中工作

C++基础知识之常量(字面量) 变量

为啥从字符串常量转换为 'char*' 在 C 中有效但在 C++ 中无效