Как использовать переменную-член в качестве аргумента по умолчанию в С++?
Я хочу, чтобы аргумент для одной из функций-членов был опциональным. Если аргумент не задан, он будет использовать переменную-член.
Однако, когда я попытался скомпилировать его, он показывает "ошибка: недопустимое использование нестатического элемента данных" 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;
};
Ответы
Ответ 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);
}