【问题标题】:Using (::) in a class's member function definition在类的成员函数定义中使用 (::)
【发布时间】:2012-10-28 21:26:29
【问题描述】:

我正在测试课程并制作了这个课程

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 类中

谁能解释一下为什么它们都有相同的效果??

谢谢。

【问题讨论】:

  • 你能解释一下为什么你认为他们的行为会有所不同吗?
  • @Johnsyweb 我认为没有 :: 运算符它不会工作,因为它会在类外搜索这些函数,因为我不再表示它们在 Point 类中
  • 简答:类成员函数定义的主体是类的范围的一部分。
  • 基本上它不会在类外搜索这个函数,因为(用leman的话来说)类内的函数是“最接近的”。

标签: c++ oop class function


【解决方案1】:

:: 是作用域解析运算符;它可以准确地告诉编译器在哪里查找名称。

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

【讨论】:

  • 我很欣赏这种努力,但这对我来说太先进了,我还在学习课程。我没有学习结构或 ->
  • @MohamedAhmedNabil:嗯......你问过,不是吗? :)
  • @EdS。我做到了,但我只是想要一个更简单的答案:)
  • @MohamedAhmedNabil 没有不牺牲完整性或真实性的更简单的答案。
  • @MohamedAhmedNabil 结构和类非常相似(将来您将了解它们之间的唯一区别)。 a-&gt;b 类似于a.b,但当a 是指向对象的指针时使用前者,而当a 是对象本身时使用后者。
【解决方案2】:

在一个类成员函数内部,所有的类成员名都在作用域内,所以找到set_x

此外,类名本身在类成员函数中是可见的(据说是注入),因此也可以找到Point::set_x。但出于同样的原因,Point::Point::set_xPoint::Point::Point::Point::set_x 也是函数的命名方式。

【讨论】:

  • 我可能会把我现在要说的带到另一个问题上,但假设:我有一个在类之外的函数,称为 printnumber。如果我在属于类 Point 的函数 setit() 中调用 printnumber()。它会起作用还是会假设 printnumber() 属于 Point
  • @MohamedAhmedNabil:全局命名空间中的所有内容也在范围内,无处不在。
【解决方案3】:

:: 是范围解析运算符。要访问 Point 类的命名空间范围内的函数,您可以使用 :: 运算符,但是因为函数 setit(int new_x, int new_y) 已经与 set_xset_y 在同一范围内,所以没有要求定义这些功能的总体范围。程序会在最局部的作用域内调用与set_xset_y匹配符号的函数。

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    相关资源
    最近更新 更多