常量字符 [] 和字符 [] 之间的区别

Difference between const char[] and char[]

本文关键字:字符 区别 常量 之间      更新时间:2023-10-16
Marray(char MyString [])
Marray(const char MyString [])

这两条线有什么区别?我正在阅读有关const char*char*之间的差异的信息。char[]const char []一样吗?我很困惑,因为在这两种情况下,当我重载运算符 [] 时,字符串文字的更改是可能的。 const char* 是指向不可变字符/字符串的可变指针。-- 所以我期待const char []也是如此,但字符串是可变的......

更多代码:

构造 函数:

Marray::Marray(const char MyString []){
    length = 0;
    while(MyString[length]!=NULL){  
        length ++;
    }
    text= new char [length+1];
    int i;
    for (i=0; i<length; i++)
        *(text+i)=MyString[i];
    text[length]=NULL;
}
char & Marray::operator[] (int i) const { return text[i];}
int main () {
    Marray n("String");
    n[3]='d';
    n.getMarray();
    system("pause");
    return 0;
}

这是我跑步后得到的:

斯特德恩

因此,即使有const char[],字符串也会更改。

我正在阅读有关const char*char*之间的差异的信息。char[]const char []一样吗?

对于大多数实际目的,答案是"是"。虽然通常char const*char const[]是两种不同的类型,但根据上下文,一种可以变成另一种。在这个特定的上下文(函数参数的声明)中,它们确实意味着同样的事情。

所以我期待const char []也是如此,但字符串是可变的

不,由于const限定符(demo),传递给函数的 C 字符串保持不变。尝试修改 Array 内部的const char MyString[]会产生编译时错误:

错误:分配只读位置"* s"

首先,根据 8.5.3 [dcl.fct] paragaph 5,函数参数类型被调整为指针类型:

。确定每个参数的类型后,"T 数组"或"返回 T 的函数"类型的任何参数将分别调整为"指向 T 的指针"或"指向返回 T 的函数的指针"。

也就是说,问题变成了"传递T*T const*有什么区别?"显而易见的答案是,所指向的物体的const性。

具有const的构造函数仅承诺不更改它收到的参数。也就是说,它承诺以下代码将写入String

char mystring[] = "String";
Marray n(mystring);
std::cout << mystring;

但是,您的类希望提供更改其内容的服务,即使传递了不可变字符串 - 因此它必须将字符串复制到另一个可变的存储中。

如果你想获得你所描述的效果,你可以创建一个不可变的对象:

char mystring[] = "String";
const Marray n(mystring);
n[3]='d'; // compilation error

更新:正如 hvd 在注释中指出的那样,要使编译器发出错误,您需要修复 operator[] 的声明:

char& Marray::operator[] (int i) { return text[i];} // non-const version
const char& Marray::operator[] (int i) const { return text[i];} // const version

或(更好)

char& Marray::operator[] (int i) { return text[i];} // non-const version
char Marray::operator[] (int i) const { return text[i];} // const version

(例如,请参阅此答案以了解为什么您需要同一运算符的 2 个版本)。