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

标签 c++ oop inheritance

我有一个简单的 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 的文档

关于C++ 继承,隐藏的基本方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3823287/

相关文章:

c++多重继承 - 编译器修改我的指针

c++ - TBB spin_mutex inside parallel_for 阻塞临界区

PHP OOP 返回并调用单个数组值

php - 在 PHP 中学习 OOP。这是正确的方法吗?

c++ - 继承构造函数和默认构造函数

c# - 通过继承构造函数来颠倒构造函数调用的顺序

c++ - 制作头文件时遇到问题

c++ - Mongoose 应该渲染一个 html 文件

algorithm - 算法的 OOP 与 PP

java - 为什么在这种情况下使用接口(interface)而不是抽象类?