36

'this'タイトルにもありますが、ポインタの型について教えていただきたいです。

私はプロジェクトに取り組んでおり、'this'ポインターのタイプが"ClassName * const this"VC++ 2008 を使用する Windows にあることを確認しました。このポインターを定数ポインターにする必要性/要件は何かを知りたいと思います。ありがとう。

4

4 に答える 4

54

このポインターの型は、クラスの非 const メソッドまたは const メソッド内で検査されるかどうかに応じて、ClassName *またはのいずれかになります。ポインターは左辺値ではありません。const ClassName *ClassNamethis

class ClassName {
  void foo() {
    // here `this` has `ClassName *` type
  }

  void bar() const {
    // here `this` has `const ClassName *` type
  }
};

上記の観察は誤解を招くものです。ポインタthis左辺値ではありませんClassName * const。つまり、型を持つことはできません。つまりconst、の右側に a を持つことはできません*。ポインター型の非左辺値は、const または非 const にすることはできません。C++ 言語にはそのような概念はまったくありません。あなたが観察したことは、特定のコンパイラの内部的な癖に違いありません。正式には、それは正しくありません。

言語仕様からの関連する引用は次のとおりです(強調鉱山)

9.3.2 this ポインタ

非静的 (9.3) メンバー関数の本体では、キーワード this は、関数が呼び出されるオブジェクトのアドレスを値とする prvalue 式です。クラス X のメンバー関数での this の型は X* です。メンバー関数が const と宣言されている場合、this の型は const X* であり、メンバー関数が volatile と宣言されている場合、this の型は volatile X* であり、メンバー関数が const volatile と宣言されている場合、this の型は const です。揮発性 X*. [注: したがって、const メンバー関数では、関数が呼び出されるオブジェクトは、const アクセス パスを介してアクセスされます。—終わりのメモ]


C++98/C++03 の時代に、いくつかのコンパイラが内部的な実装上のトリックを使用したことは何の価値もありません。たとえば、クラスの非定数メソッドで、thisポインタを定数ポインタとして解釈しました。これにより、. GCC と MSVC は、この手法を使用したことが知られています。言語レベルでは左辺値ではなく、その constness が検出されなかったため、これは無害なトリックでした。そのエクストラは、通常、コンパイラによって発行された診断メッセージでのみ明らかになります。ClassName *constClassNamethisthisconst

ただし、C++11 での右辺値参照の出現により、constの型でこのエクストラを検出できるようになりましたthis。たとえば、次のコードは C++11 で有効です。

struct S
{
  void foo() { S *&&r = this; }
};

それでも、前述のトリックをまだ使用している実装では、通常、コンパイルに失敗します。それ以来、GCC はこの手法を放棄しました。MSVC++ はまだそれを使用しており (VS2017 の時点)、上記の完全に有効なコードを MSVC++ でコンパイルできません。

于 2011-05-20T03:49:16.207 に答える
3

const は、ポインターが指すものを変更できないことを意味します。

ClassName *const

とは大きく異なります

const ClassName *

後者はオブジェクトへのポインターであり、オブジェクトを変更することはできません (とにかくポインターを使用して)。前者は、少なくとも厄介なキャストに頼らなければ、別のオブジェクト (または NULL) を再指定できないポインターです。

もちろん、次の組み合わせもあります。

const ClassName *const

これは、他の何かを指すように変更することも、それが指すオブジェクトを変更するために使用することもできないポインタです。

コンパイラがポインタを const として表示する理由については、最初のオブジェクト以外のオブジェクトを指すthisことを思いとどまらせることは理にかなっています。this

于 2011-05-20T03:49:02.430 に答える
2

上記の多くの議論があり、メインの投稿は正しい答えを示していませんでした。人々はコメントを掘らないかもしれないので、メイン ポート (PS) として共有する方が良いでしょう。

UbuntuとVC ++で調査を行いましたが、正しい出力がありません(を使用typeid(X).name)。


クラス型 X のメンバ関数に対するこのポインタの型は、X* const です。メンバー関数が const 修飾子で宣言されている場合、クラス X のそのメンバー関数の this ポインターの型は const X* const です。 MSDN リンク


概念的にもこれは正しいです。通常のメンバー関数は「X* const」であるため、左辺値ではないのです (内容を変更できないため)。

于 2014-02-24T10:39:47.813 に答える