C++;继承,隐藏基本方法 我有一个简单的C++基类,派生类例子。 // Base.hpp #pragma once class Base { public: virtual float getData(); virtual void setData(float a, float b); virtual void setData(float d); protected: float data; }; //Base.cpp #include "stdafx.h" #include "Base.hpp" float Base::getData() { return data; } void Base::setData(float a, float b) { setData(a); } void Base::setData(float d) { data = d; } //Derived.hpp #pragma once #include "Base.hpp" class Derived : public Base { public: virtual void setData(float d); }; //Derived.cpp #include "stdafx.h" #include "Derived.hpp" void Derived::setData(float d) { data = d + 10.0f; }
如果我现在将一个指针指向基,这将很好地编译C++;继承,隐藏基本方法 我有一个简单的C++基类,派生类例子。 // Base.hpp #pragma once class Base { public: virtual float getData(); virtual void setData(float a, float b); virtual void setData(float d); protected: float data; }; //Base.cpp #include "stdafx.h" #include "Base.hpp" float Base::getData() { return data; } void Base::setData(float a, float b) { setData(a); } void Base::setData(float d) { data = d; } //Derived.hpp #pragma once #include "Base.hpp" class Derived : public Base { public: virtual void setData(float d); }; //Derived.cpp #include "stdafx.h" #include "Derived.hpp" void Derived::setData(float d) { data = d + 10.0f; },c++,oop,inheritance,C++,Oop,Inheritance,如果我现在将一个指针指向基,这将很好地编译 //Main.cpp #include "stdafx.h" #include "Base.hpp" #include "Derived.hpp" Base *obj = new Derived(); 但如果我将指针指向派生类,那么编译器(VC 2008和2010)会抱怨: Main.cpp(12): error C2660: 'Derived::setData' : function does not take 2 arguments 下面是导
//Main.cpp
#include "stdafx.h"
#include "Base.hpp"
#include "Derived.hpp"
Base *obj = new Derived();
但如果我将指针指向派生类,那么编译器(VC 2008和2010)会抱怨:
Main.cpp(12): error C2660: 'Derived::setData' : function does not take 2 arguments
下面是导致此错误的代码:
//Main.cpp
#include "stdafx.h"
#include "Base.hpp"
#include "Derived.hpp"
Derived *obj = new Derived();
基类方法似乎正在被隐藏。我觉得,因为基类方法是虚拟的,即使从派生指针看,它们也应该是可见的,或者是我错了吗?< /P> < P>这是C++名称查找的一个工件。基本算法是,编译器将从当前值的类型开始,并向上执行层次结构,直到在具有目标名称的类型上找到一个成员。然后,它将仅对具有给定名称的该类型的成员执行重载解析。它不考虑在父类型上同名的成员。 解决这个问题的方法是重新定义
派生的
上的函数,然后将它们转发到基
class Derived {
...
void setData(float a, float b);
}
void Derived::setData(float a, float b) {
Base::setData(a,b);
}
此外,您还可以使用using
声明将基本成员引入范围
class Derived {
using Base::setData;
...
}
有关使用的文档
- 派生类中的函数将隐藏基类中任何同名函数
如果确实希望该名称的基类函数可见,可以添加一个using声明来实现:
class Base {
public:
void setData(float d);
void setData(float d, float e);
};
class Derived : public Base {
using Base::setData;
void SetData(float d);
};
看来我的记忆是错的。这不会导致歧义——即使使用声明,
Derived::setData
也优先(可以这么说),因此当您在派生对象上调用setData(float)
时,您会得到Derived::setData(float)
。如果将其设置为虚拟并通过指向Base的指针调用,则仍然会得到Derived::setData(float)
您的派生类是什么样子的?可能是重复的,也许您可以使用向添加一个提示?是的,这是我的建议,+1
(尽管Jared更详细地解释了原因)。