我正在用C ++编写一个小程序,我在多态中玩什么 所以代码是这样的:
//Base.h
class Base{
public:
void method(const objectType1& stuff1);
//objectType1 is whatever type you what (int, string, ...)
protected:
Base(void);
virtual ~Base(void);
virtual void method(void) = 0;
};
//Derived.h
/*FINAL - DO NOT INHERIT THIS CLASS OR YOU WILL die :)*/
class Derived : public Base{
public:
Derived(void);
~Derived(void);
private:
void method(void);
};
//Main.cpp
int main(){
objectType1 ot1;
//this code works
Base *bd = new Derived;
bd->method(ot1);
//this dosen't
Derived *dd = new Derived;
dd->method(ot1);
// he doesn't call Base::method(const objectType1& stuff1),
// he calls Derived::method(void)
return 0;
}
我通过在其他方面重命名虚拟方法void method(void)
解决了这个问题,一切都很顺利。
我的问题是:
void method(void)
中看到main
,因为protected
中的Base
和private
中的Derived
被声明为{{1}}? (这是某种副作用)谢谢:)。
答案 0 :(得分:3)
基类中的成员方法是public,这意味着任何一段代码都可以调用它。除了是公共的,它是虚拟的,这意味着执行将在运行时动态分派到最终的覆盖。
在调度调度的引用/指针的静态类型中检查静态 ,即使它将动态调度。
另一方面,在第二种情况下,调用是通过派生类型,并且在该级别检查访问说明符,其中编译器发现成员函数为private
并因此抱怨。
简单来说,当对象用作基础时,它表现为基础,但直接使用时,它的行为就像派生一样。
答案 1 :(得分:1)
Derived
中的方法定义隐藏了Base
中的定义。为避免这种情况,请将using Base::method;
添加到Derived
。
这是因为在Derived
中调用函数时,只有在Base
中的名称不正确时,编译器才会查看Derived
。请注意,它不会查找签名,而只会查找该阶段中的名称。基于签名的过载分辨率仅在之后完成。这实际上与以下情况没有太大区别:
void function(int);
void function();
int main()
{
void function(); // this declaration hides *both* global declarations
function(3); // error
}
在您的情况下,Base
扮演全局范围的角色,Derived
扮演功能范围的角色。
另请注意,这与virtaul fgunctions无关;确实如果没有virtual
也会发生同样的情况(当然,除非您通过指向Derived
的指针无法调用method
的{{1}},但会调用{而不是{1}}版本。