0

class を定義するとき、クラス名を独自の定義内で使用するときにクラス名をメンバーにclsプレフィックスする必要がありますか (または良い習慣ですか)、それとも暗黙的に行われますか? 例えばcls::cls

class cls {
    int x;
    void foo();
    void bar();
}
void cls::foo() {
    x++;    // or use cls::x?
    bar();  // or cls::bar()?
}

もしそうなら、クラスを作成するclsことは自動的にそれが名前空間でもあることを意味し::ますか?

編集 (フォローアップ):cls::または を使用しない場合、ソースにクラス外のthis->変数もある場合はどうなりますか? xどちらが参照されているかをどのようにcls::foo()知ることがx++できますか?

4

3 に答える 3

2

メンバー変数の使用をクラス名で明示的に修飾することはお勧めできません。せいぜい不要で (または必要な場合は、this->member の方が優れています)、リファクタリングを抑制します (クラスの名前を変更すると、変更する場所が増えます)。最悪の場合、仮想関数への修飾された呼び出しがオーバーライドされたバージョンにディスパッチされないため、バグが発生します。 .

于 2013-05-10T13:13:20.483 に答える
1

いいえ。少なくともそうではありません。

を使用this->して、読者にとってより明確にすることができます。しかし::、別のものです。静的メンバー変数または関数にアクセスするために使用されます。

int x;                  // Global x
namespace ot { int x; } // another x
class cls {
    int x;              // Normal member
    static int y;       // Static member
    void foo();
    static void bar();  // Static member function
}
void cls::foo() {
    this->x++;    // Modify own x. 
    x++           // Modify own x. This has implicit this->
    ::x++;        // Modify the global x.
    ot::x++;      // Modify the x in namespace ot.
    cls::y++;     // modify the static member
    cls::bar();   // static member function. same as bar()
}
于 2013-05-10T13:10:18.277 に答える
1

上に示したコードはクラスを定義していますが、最初はメンバー関数のみを宣言しています (その後すぐに定義しています)。用語は効果的なコミュニケーションにとって重要であるため、これについてのみ言及します。

クラス メンバーをインラインで定義する場合は、スコープ解決 operator ::を使用しません。次に例を示します。

class cls {
    void hello() { cout << "Hello world"; }
};

それらを個別に定義する場合は、それが必要です。そうしないと、コンパイラーは定義しようとしている関数を正確に認識できないためです。

class cls {
    void hello();
};

void cls::hello() { cout << "Hello world"; };

一般に、スコープ解決演算子の使用は名前空間の操作に限定されません。コンパイラに完全修飾名を提供する必要がある場合はいつでも使用します。

ほとんどの場合、クラス スコープ内からクラス メンバーにアクセスする場合、非修飾名を使用できます。コンパイラはそれらを独自に解決します。たとえば、コードでは、これらはすべて同等です。

x++;
cls::x++;
this->x++;
this->cls::x++; // yes, this too

同じ名前のメンバーが複数あり、コンパイラーが修飾されていない名前を意図したメンバー以外の名前に解決する場合は常に、名前を修飾する必要があります。例:

void cls::foo(int x) {
    x++;       // increments the argument
    cls::x++;  // increments the member
    this->x++; // also increments the member
}

clsから派生する可能性がありbase、 をbase定義する可能性があることも考慮してくださいx。その場合、次のように機能します。

void cls::foo() {
    x++;       // increments foo::x
    cls::x++;  // increments foo::x
    base::x++; // increments base::x
}
于 2013-05-10T13:12:59.957 に答える