1

私はクラスをテストしていて、このクラスを作りました

class Point
{
private:
    int x,y;
public:
    void setit(int new_x,int new_y);
    void set_x(int new_x);
    void set_y(int new_y);
    int get_x();
    int get_y();
};

今、私は先に進んで、すべてのパブリック関数の関数定義を書きましたが、

void set(int new_x,int new_y); 関数定義を書いているときに戸惑ったことがあります

void Point::setit(int new_x, int new_y){
    Point::set_x(new_x);
    Point::set_y(new_y);
}

void Point::setit(int new_x, int new_y){
    set_x(new_x);
    set_y(new_y);
}

前の2つの関数定義がまったく同じ効果を持っていることに気づきました。

::演算子がないと、クラス外の関数が検索されるため、機能しないと思いました。これは、それらがPointクラスにあることを意味しなくなったためです。

なぜ両方が同じ効果を持つのか誰かが説明できますか?

ありがとうございました。

4

3 に答える 3

6

::スコープ解決演算子です。名前を探す場所をコンパイラに正確に伝えることができます。

これPoint::set_xは、メンバー関数を呼び出すための単なる拡張構文です。

set_x(new_x);

の略です

this->set_x(new_x);

Point::set_x(new_x);

と同等です

this->Point::set_x(new_x);

これにより、クラスが親クラスの関数を非表示にするときに呼び出す関数を選択できます。例えば:

struct A {
    void f();
};

struct B : public A {
    void f(); // Hides A::f
};

B binst;

binst.f(); // Calls B::f

binst.A::f(); // Calls A::f

この構文で実行できることの1つは、基本クラスのオーバーライドされた仮想関数から親クラスのメンバー関数を呼び出し、基本クラスによって提供される「デフォルトの実装」を使用できるようにすることです。非表示の関数と同様に、クラスの外部からも実行できます。

struct A {
    virtual void f() {
        cout << "A::f" << endl;
    }
};

struct B : public A {
    virtual void f() override {
        cout << "B::f" << endl;

        A::f(); // if we just did f(), it would call B::f, and we
                // would get infinite recursion
    }
};

B b;

b.f();    // prints B::f A::f
b.A::f(); // prints B::f
于 2012-10-28T21:30:21.100 に答える
2

クラス メンバー関数内では、すべてのクラス メンバー名がスコープ内にあるため、set_xが見つかります。

さらに、クラス名自体はクラス メンバー関数内に表示されるため (「注入されている」と呼ばれます)、これPoint::set_xも検出されます。しかし、同じ理由でPoint::Point::set_xPoint::Point::Point::Point::set_x関数に名前を付ける方法もあります。

于 2012-10-28T21:36:17.720 に答える
1

::スコープ解決演算子です。クラスの名前空間のスコープ内の関数にアクセスするには、演算子Pointを使用できますが、関数はすでにとと同じスコープ内にあるため、これらの関数の全体的なスコープを定義する必要はありません。プログラムは、最もローカルなスコープに一致するシンボルを使用して関数を呼び出します。::setit(int new_x, int new_y)set_xset_yset_xset_y

于 2012-10-28T21:33:40.117 に答える