我有一个char *,实际上是10位数的字符串。我基本上把它放在我的函数中并吐出代码。现在我已经创建了一个静态库,我将与其他人分享......问题是(我正在使用c ++)
我将在标题中提供的api的定义 我是否只是把const char * const。我不确定我是否需要这样做。我只想到他们是否打算使用那个我不想让他们错误地在他们的代码中发送一些错误的指针或值到我的代码。所以为了保护自己我正在制作它,就像我上面说的那样正确的做法?是如何使用const?
答案 0 :(得分:6)
制作const并不意味着你不会得到一个糟糕的指针。没有什么可以做的来保护自己免受这种伤害。您可以检查NULL,但不能检查已释放的指针或已损坏的指针。
const说的是你的函数承诺不会改变指向的数据。这对调用者来说很有用。此外,如果调用者只能访问常量指针,您可以保存一个强制转换或复制来调用您的函数。
正常用法是
void makeCode(const char* s);
这意味着s指向的值不会被更改。
答案 1 :(得分:3)
添加到Lou Franco的answer,如果您要将该函数声明为:
void makeCode(const char* const s);
第二个const
表示您不会在您的函数中“重新定位”s
。这意味着您无法执行s++;
或s = anotherPtr;
。 IMO,这不是第一个const
为您的图书馆用户提供的保证。
答案 2 :(得分:1)
在一个按值获取参数的函数声明中,参数的任何const限定都将被编译器丢弃,因此我不会提供它们,因为它们是 uncommon ,因此会令人惊讶,但不会产生影响(强迫你输入6个以上的字符)。
void foo( const char * );
void foo( const char * const );
前两行是单个函数foo
的两个声明,它通过值获取指向char的指针。这与const限定指向类型或引用(其中限定条件也是引用元素)完全不同,就像在这两个声明中的第一个const一样。
定义函数时存在差异,因为在后一种情况下,编译器将强制执行参数(调用者传入的副本)将保证不在内部修改。常见的模式也不是在那里写const
,但是有些人会添加这个资格:
// foo.h
void foo( const char* ); // declaration [1]
// foo.cpp
void foo( const char * const x ) { // definition of [1]
//...
}
请注意,虽然签名可能看起来不同,但对于编译器它们完全相同,第二个const
是定义内部代码的要求,而不是函数接口的一部分。标准的适当引用见§8.3.5[dcl.fct] / 3:
[...]使用以下规则确定函数的类型。每个参数的类型由其自己的decl-specifier-seq和声明符确定。在确定每个参数的类型之后,将“T数组”或“函数返回T”类型的任何参数分别调整为“指向T的指针”或“指向函数返回T的指针”。在生成参数类型列表之后,会对这些类型进行多次转换以确定函数类型。 删除修改参数类型的任何cv-qualifier。 [示例:类型
void(*)(const int)
变为void(*)(int)
- 示例] 此类简历-qualifiers只影响函数体内参数的定义;它们不会影响功能类型。
答案 3 :(得分:0)
const char *标记的要点是向库的用户指示您的函数不会修改发送到函数的char *值。但是,这并不能保证函数不会因为const转换和其他类型的hackery而修改指针。
答案 4 :(得分:0)
如果不更改字符串,则应使用const char *。用户仍然可以发送一个非const char,它会没问题,但他会知道你没有更改字符串。 更重要的是,它更推荐,因此用户将能够在const字符串上使用您的函数,或类的const实例将能够使用您的函数等。