web-dev-qa-db-ja.com

C ++の「これ」がうまく設計されていないのはなぜですか?

  1. 同じタイプの非constポインタであるすべてのabに対して、a = b;を実行できますよね?

  2. 非constメンバー関数内には、非constポインターであるthisキーワードが存在します。論理的には、bthisと同じ型であれば、this = b;も実行できますか?

違う。

thisはポインタ構文を使用しますが、論理的にはthisが参照であるため、this = b;を実行することはできません。

しかし、なぜ地球上でthisは構文的にはポインタですが、論理的には参照なのでしょうか。

この奇妙な動作は、次のC++標準で、論理的にだけでなく構文的にも参照されるmeなどの新しいキーワードを導入することで修正できますか?

(ここでこれを解決する私の試みも参照してください: ""#define me(* this) "にするのは良い考えですか? ")

3
user3123061

thisは(nullptrのように)a 定数ポインター; constthisメンバー関数の本体にある場合に限り、ポイントされたデータはconstです。

23のような定数リテラルを変更できないように、定数ポインターを変更することはできません。

したがって、thisへの割り当ては次のようになります

this = p;  // WRONG

同じ理由でnullptrへの割り当てが禁止されています:

nullptr = 0; // wrong
30

thisは少し扱いに​​くいという議論をすることができます。
代わりにself-参照を使用すると、最近はもう少し自然に感じるでしょう。
そのタイプは、thisのタイプよりもわずかに多くの情報を運ぶことができます。つまり、次のようになります。

  1. メンバー関数が右辺値参照で呼び出されることが保証されているかどうか、および
  2. 実際には常にオブジェクトを参照していること。

それでも、C++が最終的に参照を取得したとき(演算子のオーバーロードのために発明されたと思います)、thisに関する決定はすでに古代の歴史でした。そして、後方互換性は笑い事ではありません。

0
Deduplicator

thisの設計が不十分ではありません。クラスメンバー名と同じ名前のローカル変数はほとんどありません。この構築はPODまたはほぼPODオブジェクトのコンストラクターで発生しますが、言語にはこれを処理するためのより良い方法があります。見よ:

#include <stdio.h>

class A {
    public:
        A(int m1, int m2) : m1(m1), m2(m2) {}
        int m1;
        int m2;
};

int main()
{
    A a(1, 2);
    printf("%d, %d\n", a.m1, a.m2);
}

このデモは恐怖に満ちていることに同意できると確信していますが、要点は明らかです。コンストラクターには、メンバーと同じ名前のローカル変数があり、ローカル変数と同じ名前のメンバーを初期化します。このプログラムを実行して、出力「1、2」を取得できます。

また、C++では、実際の実装に対して、適切なパラメーター名(ヒント用)と不適切な名前を持つ関数を宣言できると予想されます。これは、インライン関数をクラス定義で個別に宣言するのではなく、個別に宣言する場合でも実行できます。

これらすべての理由から、メンバー関数がそのクラスに明示的にアクセスする必要はめったになく、そのポインターのみにアクセスする必要があります。したがって、thisキーワードはポインターです。

歴史的遺物:thisはかつてconstではなく、割り当てることができました。これは悪い考えでした。

0
Joshua