Как использовать переменную-член в качестве аргумента по умолчанию в C++?
Я хочу сделать аргумент для одной из функций-членов необязательным. Когда аргумент не предоставлен, он будет использовать переменную-член.
Тем не менее, когда я пытался скомпилировать его, он показывает "ошибка: недопустимое использование нестатического члена данных" 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 ответа
Выражения аргументов по умолчанию для функции-члена могут зависеть только от того, что находится в классе или глобальной области видимости. Аргумент по умолчанию также должен быть указан в объявлении метода (то есть в заголовочном файле).
Чтобы обойти это, вам нужно 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
только один раз, тем самым соблюдая принцип СУХОГО.
Значения по умолчанию не являются частью прототипа, то есть они разрешаются вызывающей стороной, а не самой функцией. Итак, во-первых, они должны быть видны звонящему. Во-вторых, они не могут получить доступ к защищенным членам класса. (Я почти уверен, что вы не можете использовать публичных участников по умолчанию, но я слишком устал, чтобы проверять.)
Чтобы решить проблему, используйте цепные перегрузки, как предложено в других ответах.
Вы можете перегрузить свой член функции следующим образом:
void Object::MoveTo(double speed, Point position) {
....
}
void Object::MoveTo(double speed) {
Point position = this->initPos;
MoveTo(speed, position);
}
Помимо перегрузки, существует другой подход - передача недопустимого значения в качестве значения по умолчанию. Затем проверьте это внутри своей функции.
void Object::MoveTo(double speed, Point position = InvalidPosition) {
position = (position != InvalidPosition) ? position : initPos;
...
}