简体   繁体   English

从字符串const转换为不推荐的转换。 到wchar_t *

[英]Deprecated conversion from string const. to wchar_t*

Hello I have a pump class that requires using a member variable that is a pointer to a wchar_t array containing the port address ie: "com9". 你好我有一个泵类需要使用一个成员变量,该变量是一个指向包含端口地址的wchar_t数组的指针,即:“com9”。

The problem is that when I initialise this variable in the constructor my compiler flags up a depreciated conversion warning. 问题是,当我在构造函数中初始化此变量时,我的编译器会标记折旧的转换警告。

pump::pump(){
   this->portNumber = L"com9";}

This works fine but the warning every time I compile is anoying and makes me feel like I'm doing something wrong. 这工作正常但每次编译时的警告都很烦人,让我觉得我做错了什么。

I tried creating an array and then setting the member variable like this: 我尝试创建一个数组,然后像这样设置成员变量:

pump::pump(){
   wchar_t port[] = L"com9";
   this->portNumber = port;}

But for some reason this makes my portNumber point at 'F'. 但由于某种原因,这使我的portNumber指向'F'。

Clearly another conceptual problem on my part. 显然,我的另一个概念问题。

Thanks for help with my noobish questions. 感谢您对我的无聊问题的帮助。

EDIT: 编辑:

As request the definition of portNumber was: 作为请求,portNumber的定义是:

    class pump
{
private:
   wchar_t* portNumber;
}

Thanks to answers it has now been changed to: 感谢答案,它现在已更改为:

    class pump
{
private:
   const wchar_t* portNumber;
}

If portNumber is a wchar_t* , it should be a const wchar_t* . 如果portNumberwchar_t* ,则它应该是const wchar_t*

String literals are immutable, so the elements are const . 字符串文字是不可变的,因此元素是const There exists a deprecated conversion from string literal to non-const pointer, but that's dangerous. 存在从字符串文字到非常量指针的不推荐的转换,但这是危险的。 Make the change so you're keeping type safety and not using the unsafe conversion. 进行更改,以确保类型安全,不使用不安全的转换。

The second one fails because you point to the contents of a local variable. 第二个失败是因为您指向局部变量的内容。 When the constructor finishes, the variable goes away and you're pointing at an invalid location. 当构造函数完成时,变量消失,你指向一个无效的位置。 Using it results in undefined behavior. 使用它会导致未定义的行为。

Lastly, use an initialization list: 最后,使用初始化列表:

pump::pump() :
portNumber(L"com9")
{}

The initialization list is to initialize, the constructor is to finish construction. 初始化列表是初始化,构造函数是完成构造。 (Also, this-> is ugly to almost all C++ people; it's not nice and redundant.) (另外, this->是丑陋的几乎所有C ++的人,这不是很好的和多余的。)

Use const wchar_t* to point at a literal. 使用const wchar_t*指向文字。

The reason the conversion exists is because it has been valid from early versions of C to assign a string literal to a non-const pointer[*]. 转换存在的原因是因为它从C的早期版本开始有效,将字符串文字分配给非常量指针[*]。 The reason it's deprecated is that it's invalid to modify a literal, and it's risky to use a non-const pointer to refer to something that must not be modified. 它被弃用的原因是它修改文字是无效的,使用非const指针来引用一些不能被修改的东西是有风险的。

[*] C didn't originally have const . [*] C最初没有const When const was added, clearly it should apply to string literals, but there was already code out there, written before const existed, that would break if suddenly you had to sprinkle const everywhere. 当添加const时,显然它应该适用于字符串文字,但是已经存在代码,在const存在之前编写,如果突然你不得不在每个地方撒上const ,那就会破坏。 We're still paying today for that breaking change to the language. 我们今天仍在为这种语言的突破性变化付出代价。 Since it's C++ you're using, it wasn't even a breaking change to this language. 因为它是你正在使用的C ++,所以它甚至不是对这种语言的重大改变。

Apparently, portNumber is a wchar_t * (non-const), correct? 显然, portNumber是一个wchar_t * (非常量),对吗? If so: 如果是这样的话:

  • the first one is wrong, because string literals are read-only (they are const pointers to an array of char usually stored in the string table of the executable, which is mapped in memory somewhere, often in a readonly page). 第一个是错误的,因为字符串文字是只读的(它们是指向通常存储在可执行文件的字符串表中的char数组的const指针,这些字符串映射到某处的内存中,通常位于只读页面中)。
    The ugly, implicit conversion to non-const char s/ wchar_t s was approved, IIRC, to achieve compatibility with old code written when const didn't even existed; 对于非const char s / wchar_t s的丑陋,隐式转换被批准,IIRC,以实现与const甚至不存在时编写的旧代码的兼容性; sadly, it let a lot of morons which do not know what const correctness means get away with writing code that asks non-const pointers even when const pointers would be the right choice. 遗憾的是,它让许多不知道const正确意味着什么意思的蠢货逃脱了编写代码,即使当const指针是正确的选择时,也会询问非常量指针。

  • The second one is wrong because you're making portNumber point to a variable allocated on the stack, which is deleted when the constructor returns. 第二个是错误的,因为你正在使portNumber指向在堆栈上分配的变量,当构造函数返回时,该变量将被删除。 After the constructor returns, the pointer stored in portNumber points to random garbage. 构造函数返回后,存储在portNumber的指针指向随机垃圾。

The correct approach is to declare portNumber as const wchar_t * if it doesn't need to be modified. 正确的方法是将portNumber声明为const wchar_t *如果它不需要修改。 If, instead, it does need to be modified during the lifetime of the class, usually the best approach is to avoid C-style strings at all and just throw in a std::wstring , that will take care of all the bookkeeping associated with the string. 相反,如果它确实需要在类的生命周期中进行修改,通常最好的方法是避免使用C风格的字符串,只需要输入一个std::wstring ,它将处理与之相关的所有簿记。字符串。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM