简体   繁体   English

为什么初始化char * []时需要const而string []不需要?

[英]Why does Initializing char*[] require const while string[] doesn't?

char* c_arguments[] = { "hi","bye" }; //(1)
std::string cpp_arguments[]= { "hi","bye" };

(1) gives error in Visual Studio under C++17 standard (1)在C ++ 17标准下在Visual Studio中给出错误

E0144: A value of type “const char*” cannot be used to initialize an entity of type “char *” E0144:“ const char *”类型的值不能用于初始化“ char *”类型的实体

If I add const in the beginning the code compiles fine. 如果我在开始时添加const ,则代码可以正常编译。

But why does the first line require const but the second line does not? 但是为什么第一行需要const但第二行不需要const?

How to create char*[] without const from an array of string literals? 如何从字符串文字数组中创建不带const的char*[]

The code can use features of latest C++ standards and doesn't have to consider legacy systems. 该代码可以使用最新的C ++标准的功能,而不必考虑旧系统。

The second line is calling copy constructors. 第二行是调用复制构造函数。 Even though the literals are read-only the copies are not. 即使文字是只读的,副本也不是。

To create a pointer array to writable strings, you'll have to loop through and create a copy of each literal, just like the std::string constructor would do. 要创建一个指向可写字符串的指针数组,您必须像std::string构造函数那样循环遍历并创建每个文字的副本。

Strings are objects, under the hood, the compiler is creating two const char* buffers, and then copying those values into the string objects to give you mutable arrays. 字符串是对象,实际上,编译器正在创建两个const char*缓冲区,然后将这些值复制到字符串对象中以提供可变数组。 You could do the same to create your char* pointers if you wanted. 如果需要,您可以执行相同的操作来创建char*指针。

I wouldn't suggest using literal char* pointers without const in C++. 我不建议在C ++中使用不带const的文字char*指针。 There are a lot of ways to mess them up. 有很多方法可以弄乱它们。 If you want to modify a character buffer you should wrap them in a string and use the appropriate library functions. 如果要修改字符缓冲区,则应将它们包装在字符串中并使用适当的库函数。

The first type c_ is an array of pointers to char . 第一种类型c_char的指针数组。 The second type cpp_ is an array of std::string s. 第二种类型cpp_std::string的数组。

When you pass a "string" to a pointer, it generates the pointer to the first element. 当您将"string"传递给指针时,它将生成指向第一个元素的指针。 But the type of the data in "hello" is const ; 但是"hello"中的数据类型是const ; so a char* does not want to point at it. 因此char*不想指向它。 Instead you need a char const* , or a pointer to const char s. 相反,您需要使用char const*或指向const char的指针。

For a std::string , when you pass "hello" to it, it copies the characters into a buffer owned by the std::string . 对于std::string ,当您向其传递"hello"时,会将字符复制std::string拥有的缓冲区中。 The copy can be mutable, so there is no need for const . 该副本可以是可变的,因此不需要const

There are compiler flags that discard the need for const when assigning a "hello" string literal to a char* ; 在将"hello"字符串文字分配给char*时,有一些编译器标志会放弃对const的需要; they, however, exist for compatibility with code written before const was a thing. 但是,它们的存在是为了与const之前编写的代码兼容。 Avoid using them. 避免使用它们。 If you modify, accidentally, the string constant after using those flags, you have undefined behaviour going on (most likely with string pooling you'll cause insanity) 如果您在使用这些标志后意外地修改了字符串常量,则可能会发生不确定的行为(很可能在字符串池中造成精神错乱)

In c++ there are essentially primitive data types and user defined data types. 在c ++中,本质上有原始数据类型和用户定义的数据类型。 Primitive data types like int, char, pointers are built into the language. 语言中内置了int,char,pointers等原始数据类型。 User defined types are built on the top of the primitive types. 用户定义的类型建立在基本类型的顶部。

Some of C++ user defined types are classes which can do some user defined actions under the hood. 一些C ++用户定义类型是可以在后台执行某些用户定义操作的类。 std::string is such a type. std::string就是这种类型。 Objects of type string are initialized using a constructor. 使用构造函数初始化字符串类型的对象。

All quoted string in c++ are const set of characters, meaning that the program has no right to modify them. c ++中所有引用的字符串都是const字符集,这意味着程序无权修改它们。

const char *str = "abc"; just declares a pointer to the constant string 'abc'. 只需声明一个指向常量字符串“ abc”的指针即可。 Therefore it must be 'const'. 因此,它必须是“ const”。

std::string stdstr = "abc"; declares an object of class string from the namespace std . 从名称空间std声明一个string类的对象。 The initialization of the object calls a constructor of the string . 对象的初始化调用string的构造函数。 The latter copies the string into internal storage. 后者将字符串复制到内部存储中。 Copy cannot modify the "abc" character set. 复制不能修改“ abc”字符集。 So, there is no conflict. 因此,没有冲突。

In the first case you cannot modify the pointer, in other words str[1] = 'd'; 在第一种情况下,您不能修改指针,换句话说就是str[1] = 'd'; is illegal. 是非法的。 it tires to modify the constant (read-only) string directly. 它会直接修改常量(只读)字符串。 In the second case you can modify the copy of "abc". 在第二种情况下,您可以修改“ abc”的副本 stdstr[1] = 'd'; is legal. 是合法的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 string 在这里不起作用而 char const* 可以? - Why does string not work here while char const* does? 为什么C不允许从char **到const char * const *(和C ++)的隐式转换? - Why C doesn't allow implicit conversion from char ** to const char *const * (and C++ does)? 为什么MSVC不为cout或const char *优化cout,但它对int有效? - Why doesn't MSVC optimize cout for char or const char* but it does for int? 为什么不strlen(..)期望const char * const str而不是const char * - why doesn't strlen (..) expect const char* const str instead of const char* 允许为std :: string分配“const char *”,但是不能编译分配给std :: wstring。 为什么? - Assigning a “const char*” to std::string is allowed, but assigning to std::wstring doesn't compile. Why? 为什么字符串(const char * s,size_t pos,size_t len = npos)有效? - Why does string (const char* s, size_t pos, size_t len = npos) work? 为什么ostream :: write()在C ++中需要'const char_type *'而不是'const void *'? - Why does ostream::write() require ‘const char_type*’ instead of ‘const void*’ in C++? 在c ++中初始化引用不起作用,但是初始化const引用有效,为什么? - initializing references in c++ doesn't work but initializing const references works, why? 在 fstream 中,为什么 read() 和 write() 需要 const char*? - In fstream, why read() and write() require const char*? 如果字符串不等于const char,则退出while循环 - If string does not equal const char break out of while loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM