我想为其中一个成员函数选择一个参数。如果没有提供参数,它将使用成员变量。
然而,当我尝试编译它时,它显示“错误:无效使用非静态数据成员'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;
};
答案 0 :(得分:41)
成员函数的默认参数表达式只能依赖于类或全局范围内的事物。默认参数也必须在方法的声明中指定(即在头文件中)。
要解决此问题,您需要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原则。
答案 1 :(得分:12)
默认值不是原型的一部分,即它们由调用者解决,而不是由函数本身解析。首先,它们必须对呼叫者可见。其次,他们无法访问该类的受保护成员。 (我很确定你甚至不能使用公共成员作为默认值,但我太累了,无法检查。)
要解决此问题,请使用其他答案中建议的链式重载。
答案 2 :(得分:1)
您可以像这样重载您的函数成员:
void Object::MoveTo(double speed, Point position) {
....
}
void Object::MoveTo(double speed) {
Point position = this->initPos;
MoveTo(speed, position);
}
答案 3 :(得分:0)
除了重载,另一种方法是传递一个无效值作为默认值。然后在您的函数中检查它。
inline static unsigned f0( unsigned aa, unsigned bb)
{
return aa %bb + bb %aa;
}
#if WANT_MAGIC /* not needed, anyway */
#define MAGIC __attribute__ ((noinline))
#else
#define MAGIC /**/
#endif
unsigned MAGIC f1( unsigned aa, unsigned bb)
{
return f0( aa, bb);
}
unsigned MAGIC f2( unsigned aa, unsigned bb)
{
return f0( aa, bb);
}