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);
}

我注意到前面的两个函数定义具有完全相同的效果。

我认为没有 :: 运算符它不会工作,因为它会搜索类外的函数,因为我不再表示它们在 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

您可以使用此语法做的一件事是从基类的重写虚函数调用父类的成员函数,从而允许您使用基类提供的“默认实现”。你也可以在类外进行,类似于隐藏函数:

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)已经与 and 在同一范围内set_xset_y因此不需要定义这些函数的整体范围。该程序将在最本地范围内调用具有匹配符号set_x的函数。set_y

于 2012-10-28T21:33:40.117 回答