IT虾米网

C++ 继承,隐藏的基本方法

JustinYoung 2023年09月15日 编程语言 31 0

我有一个简单的 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; 
} 

如果我现在创建一个指向 Base 的指针,则可以正常编译。

//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(); 

似乎基类方法被隐藏了。我的印象是,由于基类方法是虚拟的,即使从 Derived 指针查看它们也应该是可见的,或者我错了吗?

请您参考如下方法:

这是 C++ 名称查找的神器。基本算法是编译器将从当前值的类型开始并沿着层次结构向上处理,直到找到具有目标名称的类型的成员。然后它将只对具有给定名称的该类型的成员进行重载决策。它不考虑父类型上的同名成员。

解决这个问题的方法是重新定义 Derived 上的函数,并将它们转发到 Base

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 的文档


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!