Как использовать переменную-член в качестве аргумента по умолчанию в C ++? - PullRequest
30 голосов
/ 15 февраля 2012

Я хочу сделать аргумент для одной из функций-членов необязательным.Когда аргумент не предоставлен, он будет использовать переменную-член.

Однако, когда я пытался скомпилировать его, он показывает « ошибка: недопустимое использование элемента не статических данных 'Object :: initPos' "

Просто для изоляциипроблема, я попытался по умолчанию тип int, и он скомпилирован нормально.Интересно, в чем проблема с моим кодом и как я могу использовать функцию-член в качестве значения по умолчанию.

Спасибо за вашу помощь!

Object.h

class Object
{
    public:
       ...
       void MoveTo(double speed, Point position);

    protected:
       Point initPos; 
       Point currPos;

};

Object.c

void Object::MoveTo(double speed, Point position = initPos)
{
    currPos = postion;
}

Point.h

class Point
{
    ...

    private:
       double x;
       double y;
       double z; 
};

Ответы [ 3 ]

41 голосов
/ 15 февраля 2012

Выражения аргументов по умолчанию для функции-члена могут зависеть только от того, что находится в классе или в глобальной области видимости. Аргумент по умолчанию также должен быть указан в объявлении метода (то есть в заголовочном файле).

Чтобы обойти это, вам нужно 2 перегрузки метода MoveTo. Один принимает 1 аргумент, а другой - 2 аргумента. Метод, принимающий 1 аргумент, вызывает другой метод, передавая значение, которое вы считаете значением по умолчанию.

void Object::MoveTo(double speed)
{
    MoveTo(speed, initPos);
}

void Object::MoveTo(double speed, Point position)
{
    // Everything is done here.
}

Обратите внимание, что когда вы делаете MoveTo(double) вызов MoveTo(double, Point), это позволяет вам написать реализацию MoveTo только один раз, тем самым соблюдая принцип DRY .

12 голосов
/ 15 февраля 2012

Значения по умолчанию не являются частью прототипа, то есть они разрешаются вызывающей стороной, а не самой функцией. Итак, во-первых, они должны быть видны звонящему. Во-вторых, они не могут получить доступ к защищенным членам класса. (Я почти уверен, что вы не можете использовать публичных участников по умолчанию, но я слишком устал, чтобы проверять.)

Чтобы решить проблему, используйте цепные перегрузки, как предложено в других ответах.

1 голос
/ 15 февраля 2012

Вы можете перегрузить свой элемент функции следующим образом:

void Object::MoveTo(double speed, Point position) {
   ....
}

void Object::MoveTo(double speed) {
   Point position = this->initPos;

   MoveTo(speed, position);
}
...