двойное двоеточие (::) перед объявлением метода в определении класса

У меня есть класс, написанный третьей стороной, который имеет что-то вроде этого Foo.h:

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

    //Other things here
};

А в Foo.cpp dosomething это:

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.


person 7VoltCrayon    schedule 24.06.2015    source источник
comment
Foo в int Foo::dosomething(float x, float y, float z); в объявлении класса является дополнительным и плохо отформатированным С++. (Некоторые компиляторы выдают предупреждение, другие его игнорируют)   -  person    schedule 24.06.2015
comment
MSVC2013 32-бит (с использованием QT Creator IDE)   -  person 7VoltCrayon    schedule 24.06.2015


Ответы (2)


Как правило, незаконно использовать оператор области видимости :: для существующей области видимости класса для ссылки на его собственные члены (даже если это избыточно).

После объявления члена класса имя члена можно найти в области видимости его класса. [ Примечание: это верно, даже если класс является неполным. Например, 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 нет исключений для членов класса.

Даже с указанным выше ограничением синтаксис для членов класса не запрещает использование полного идентификатора для имени члена. Следовательно, принятие показанного кода не является синтаксической ошибкой. Но есть семантическое нарушение, и должна была быть выдана диагностика.

person jxh    schedule 24.06.2015

Неправильно (и многие компиляторы считают это ошибкой) добавлять область действия к имени функции внутри определения класса. Поскольку он уже находится в рамках класса, вы, по сути, определяете область функций как 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.

person Cory Kramer    schedule 24.06.2015