为什么这段代码无法编译? (gcc 4.7.0)
// Class with a simple getter/setter pair.
class Base {
public:
Base () : m_Value(0) { }
virtual ~Base () { }
// Getter
virtual int value () { return m_Value; }
// Setter
virtual void value (int Val) { m_Value = Val; }
private:
int m_Value;
};
// Derived class overrides the setter.
class Derived : public Base {
public:
void value (int Val) {
// do some stuff here...
}
};
int main()
{
Derived * instance = new Derived();
int x = instance->value(); // ERROR
return 0;
}
构建日志:
test.cpp: In function 'int main()':
test.cpp:29:25: error: no matching function for call to 'Derived::value()'
test.cpp:29:25: note: candidate is:
test.cpp:21:7: note: virtual void Derived::value(int)
test.cpp:21:7: note: candidate expects 1 argument, 0 provided
为什么编译器在使用Derived *?
时无法从Base看到'int value()'更改
Derived * instance = new Derived();
到
Base * instance = new Derived();
有效(但在我的情况下我需要派生指针)。
还将基本getter / setter函数重命名为getValue()和setValue(int)。我可以为我的代码使用各种变通方法,但我只是好奇为什么这段代码无法编译。
答案 0 :(得分:11)
这就是语言的工作方式:当子类重写名称的成员时,它会隐藏父语句中所有未重写的名称。这是为了防止意外组合应该作为集重写的基本方法和父方法。
您可以将using Base::value;
放入子类中以引入父方法。
答案 1 :(得分:3)
派生类中的函数value
隐藏基类中的函数。
您需要将基类函数放在派生类的范围内:
class Derived : public Base {
public:
using Base::value; //<---- note this
void value (int Val) {
// do some stuff here...
}
};
答案 2 :(得分:2)
除了给出的其他答案之外,除了在子类中添加using Base::value
之外,您还可以执行以下操作,
int x = instance->Base::value();
您明确告诉编译器使用Base
的值函数。虽然从技术上说这是有效的,但它会强制一些间接性,如果你发现自己经常这样做,你可能想重新考虑如何构建你的代码。