Подтвердить что ты не робот

Как использовать переменную-член в качестве аргумента по умолчанию в С++?

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

Однако, когда я попытался скомпилировать его, он показывает "ошибка: недопустимое использование нестатического элемента данных" 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; 
};
4b9b3361

Ответ 1

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

Чтобы обойти это, вам понадобится 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.

Ответ 2

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

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

Ответ 3

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

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

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

   MoveTo(speed, position);
}