7

こんにちは、「com9」などのポート アドレスを含む wchar_t 配列へのポインターであるメンバー変数を使用する必要があるポンプ クラスがあります。

問題は、コンストラクターでこの変数を初期化すると、コンパイラーが減価償却の警告を出すことです。

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

これは問題なく動作しますが、コンパイルするたびに警告が表示されるのが面倒で、何か間違ったことをしているように感じます。

配列を作成してから、メンバー変数を次のように設定してみました。

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

しかし、何らかの理由で、これによりポート番号が「F」を指します。

明らかに、私の側の別の概念上の問題です。

私の初心者の質問を手伝ってくれてありがとう。

編集:

リクエストに応じて、portNumber の定義は次のとおりです。

    class pump
{
private:
   wchar_t* portNumber;
}

回答のおかげで、次のように変更されました。

    class pump
{
private:
   const wchar_t* portNumber;
}
4

3 に答える 3

13

portNumberが の場合wchar_t*、 である必要がありconst wchar_t*ます。

文字列リテラルは不変であるため、要素はconst. 文字列リテラルから非 const ポインターへの非推奨の変換が存在しますが、これは危険です。タイプ セーフを維持し、安全でない変換を使用しないように変更します。

2 つ目は、ローカル変数の内容を指しているため失敗します。コンストラクターが終了すると、変数はなくなり、無効な場所を指しています。これを使用すると、未定義の動作が発生します。

最後に、初期化リストを使用します。

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

初期化リストは初期化することであり、コンストラクターは構築を終了することです。(また、this->ほとんどすべての C++ の人々にとって醜いものです。それは良くも冗長でもありません。)

于 2010-09-23T14:27:47.133 に答える
2

const wchar_t*リテラルを指すために使用します。

変換が存在する理由は、文字列リテラルを非 const ポインター [*] に割り当てることが C の初期のバージョンから有効であったためです。非推奨の理由は、リテラルを変更することは無効であり、非 const ポインターを使用して変更してはならないものを参照するのは危険だからです。

[*] C にはもともと がありませんでしたconst。が追加されたときconst、明らかにそれは文字列リテラルに適用されるはずですが、存在する前に書かれたコードがすでにそこにあり、突然どこにでもconst振りかける必要があると壊れてしまいます. const言語への重大な変更に対して、今日でも支払いを行っています。使用しているのは C++ であるため、この言語に対する重大な変更はありませんでした。

于 2010-09-23T14:28:21.187 に答える
1

どうやら、portNumberwchar_t *非定数)は正しいですか?もしそうなら:

  • 文字列リテラルは読み取り専用であるため、最初のものは間違っています(通常、実行可能ファイルの文字列テーブルに格納されている char の配列への const ポインターであり、メモリのどこかに、多くの場合読み取り専用ページにマップされます)。
    非 const chars/ s への醜く暗黙的な変換は、IIRC によって承認され、存在すらしていなかっwchar_tたときに書かれた古いコードとの互換性を実現しました。悲しいことに、 const の正確性constが何を意味するのかを知らない多くの愚か者が、const ポインターが正しい選択であっても非 const ポインターを要求するコードを書くことから逃れることができます。

  • portNumberコンストラクターが戻ると削除される、スタックに割り当てられた変数を指摘しているため、2 つ目は間違っています。コンストラクターが戻った後、格納されているポインターはportNumberランダムなガベージを指します。

正しいアプローチは、変更する必要がないかのようportNumberに宣言することです。const wchar_t *代わりに、クラスの存続期間中に変更する必要がある場合通常、最善の方法は、C スタイルの文字列をまったく使用せずに をスローするstd::wstringことです。これにより、文字列に関連付けられたすべての簿記が処理されます。

于 2010-09-23T14:29:14.457 に答える