2

我有一个由第 3 方编写的课程,其中包含类似 Foo.h 的内容:

class Foo
{
public:
    int Foo::dosomething(float x, float y, float z);

    //Other things here
};

在 Foo.cpp 中,dsomething 是:

int Foo::dosomething(float x, float y, float z)
{    
    //Something
}

::标题中的函数名称之前的含义是什么?当我创建一个新对象时

Foo foo;

我无法像这样访问 dosomething 功能:

foo.dosomething(1,2,3);

dosomething 是如何被访问的?当我在执行以下操作之前删除头文件中的 :: 时:

class Foo
{
public:
    int dosomething(float x, float y, float z);

    //Other things here
};

我可以从 Foo 类型的对象访问 dosomething。

4

2 回答 2

5

将作用域添加到类定义的函数名是不正确的(许多编译器认为这是一个错误) 。由于它已经在类的范围内,因此您实际上是在将函数范围定义Foo::Foo::dosomething为错误的。

class Foo
{
public:
    int Foo::dosomething(float x, float y, float z);   // Shouldn't have Foo::
};

为了回答你的问题::,它指定了函数的范围。考虑这两个函数

int dosomething(float x, float y, float z);
int Foo::dosomething(float x, float y, float z);

第一个是自由函数,后者是Foo类的方法并且(因为它前面没有单词)需要调用static的实例。Foo

于 2015-06-24T18:02:42.833 回答
1

一般来说,针对现有类作用域使用作用域运算符来引用它自己的成员是不违法::的(即使它是多余的)。

在类成员的声明点之后,可以在其类的范围内查找成员名称。[注意:即使课程是不完整的课程也是如此。例如, struct X {
enum E { z = 16 };
int b[X::z];         // OK
};
C++11 §3.3.2 ¶5

问题是声明点的定义似乎排除了在成员声明中使用范围运算符(如果它是在其自己的名称上)。

名称的声明点紧跟在它的完整声明符(第 8 条)之后和它的初始化器(如果有的话)之前,除非下面提到。[示例:
int x = 12;
{ int x = x; }
这里第二个x用它自己的(不确定的)值初始化。— 结束示例]
C++11 §3.3.2 ¶1

在第 3.3.2 节的其余部分中,类成员没有例外。

即使有上述限制,类成员的语法也不禁止对成员名称使用限定 ID。因此,接受显示的代码不是语法错误。但是,存在语义冲突,应该发出诊断信息。

于 2015-06-24T23:45:34.873 回答