已弃用字符串 const 的转换。到 wchar_t*

发布于 2024-09-24 19:15:23 字数 665 浏览 8 评论 0原文

您好,我有一个泵类,需要使用一个成员变量,该变量是指向包含端口地址的 wchar_t 数组的指针,即:“com9”。

问题是,当我在构造函数中初始化此变量时,我的编译器会标记折旧转换警告。

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

这工作正常,但每次编译时的警告都很烦人,让我觉得我做错了什么。

我尝试创建一个数组,然后像这样设置成员变量:

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

但由于某种原因,这使我的 portNumber 指向“F”。

显然我的另一个概念问题。

感谢您对我的新手问题的帮助。

编辑:

根据请求, portNumber 的定义是:

    class pump
{
private:
   wchar_t* portNumber;
}

感谢答案,现在已更改为:

    class pump
{
private:
   const wchar_t* portNumber;
}

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".

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'.

Clearly another conceptual problem on my part.

Thanks for help with my noobish questions.

EDIT:

As request the definition of portNumber was:

    class pump
{
private:
   wchar_t* portNumber;
}

Thanks to answers it has now been changed to:

    class pump
{
private:
   const wchar_t* portNumber;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘香 2024-10-01 19:15:23

如果 portNumberwchar_t*,则它应该是 const wchar_t*

字符串文字是不可变的,因此元素是 const。存在从字符串文字到非常量指针的已弃用转换,但这很危险。进行更改,以便保持类型安全并且不使用不安全的转换。

第二个失败,因为您指向局部变量的内容。当构造函数完成时,变量消失并且您指向无效位置。使用它会导致未定义的行为。

最后,使用初始化列表:

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

初始化列表用于初始化,构造函数用于完成构造。 (此外,this-> 对于几乎所有 C++ 人来说都是丑陋的;它既不好又多余。)

If portNumber is a wchar_t*, it should be a const wchar_t*.

String literals are immutable, so the elements are 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.)

ぽ尐不点ル 2024-10-01 19:15:23

使用 const wchar_t* 指向文字。

存在转换的原因是因为从 C 的早期版本开始,将字符串文字分配给非常量指针 [*] 是有效的。它被弃用的原因是修改文字是无效的,并且使用非常量指针来引用不得修改的内容是有风险的。

[*] C 最初没有 const。当添加 const 时,显然它应该适用于字符串文字,但是已经有代码在 const 存在之前编写,如果突然必须撒上<,这些代码就会中断。 code>const 无处不在。时至今日,我们仍在为语言的重大改变付出代价。由于您使用的是 C++,因此这甚至不是对该语言的重大更改。

Use const wchar_t* to point at a literal.

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[*]. 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.

[*] C didn't originally have 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. 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.

不语却知心 2024-10-01 19:15:23

显然, portNumber 是一个 wchar_t * (非常量),对吗?如果是这样:

  • 第一个是错误的,因为字符串文字是只读的(它们是指向 char 数组的 const 指针通常存储在可执行文件的字符串表中,该数组映射在内存某处,通常在只读页面中)。
    IIRC 批准了对非 const chars/wchar_ts 的丑陋隐式转换,以实现与 const 不使用时编写的旧代码的兼容性甚至不存在;遗憾的是,它让很多不知道 const 正确性意味着什么的白痴们编写了询问非 const 指针的代码,即使 const 指针是正确的选择。

  • 第二个是错误的,因为您使 portNumber 指向在堆栈上分配的变量,该变量在构造函数返回时被删除。构造函数返回后,存储在 portNumber 中的指针指向随机垃圾。

正确的做法是,如果不需要修改,将portNumber声明为const wchar_t *。相反,如果它确实需要在类的生命周期内进行修改,通常最好的方法是完全避免 C 风格的字符串,而只是抛出一个 std::wstring< /code>,它将处理与字符串相关的所有簿记。

Apparently, portNumber is a wchar_t * (non-const), correct? 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).
    The ugly, implicit conversion to non-const chars/wchar_ts was approved, IIRC, to achieve compatibility with old code written when const didn't even existed; 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.

  • 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. After the constructor returns, the pointer stored in portNumber points to random garbage.

The correct approach is to declare portNumber as const wchar_t * if it doesn't need to be modified. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文