【问题标题】:Why won't derived class access a non-virtual base class function?为什么派生类不能访问非虚拟基类函数?
【发布时间】:2013-09-26 20:56:58
【问题描述】:

我无法让派生类访问基类中定义的函数。名为 Particle.h 的基类头文件是:

class Particle {
    protected:
        vector<double> x_,y_,z_;

        // lots of other protected members that are not relevant to the question

    public:

        // constructors and other functions not relevant to question are omitted
        virtual double getX(const unsigned int index, const double theta, const double phi);
        virtual vector<double> getX(const double theta, double Real phi);
        vector<double> getX(const unsigned int surfindex);
}

这个函数的定义在一个名为 Particle.cc 的文件中:

#include "Particle.h"

vector<double> Particle::getX(const unsigned int surfindex)
{
    vector<double> xp;
    xp.clear();
    xp.resize(3,0.0);
    xp[0] = x_.at(surfindex);
    xp[1] = y_.at(surfindex);
    xp[2] = z_.at(surfindex);

    return xp;
}

派生类头文件 Star.h 是:

#include "Particle.h"

using namespace std;

class Star : public Particle {

    public:

       // constructors and other functions not relevant to question are omitted here

       virtual void computeRoundness(const unsigned int method);
       double getX(const unsigned int index, const double theta, const double phi);
       vector<double> getX(const double theta, double Real phi);
}

computeRoundness 函数的定义在名为 Star.cc 的文件中:

#include "Star.h"

// Lots of other function definitions not relevant to question are omitted here

void Star::computeRoundness(const unsigned int method)
{
    vector<double> X;
    unsigned int count = 0;
    while (count < ntheta) {
       X = getX(count);      // Should call base class function, right?

       // do some more things with X that are not relevant to this question
    }
}

但我收到此编译时错误:

Star.cc: In member function ‘virtual void Star::computeRoundness(unsigned int)’:
Star.cc:1340: error: no matching function for call to ‘Star::getX(unsigned int&)’
Star.h:687: note: candidates are: virtual double Star::getX(unsigned int, double, double)
Star.h:696: note:                 virtual std::vector<double, std::allocator<double> > Star::getX(double, double)

我过去在其他C++项目中已经成功地从派生类中调用了基类函数,所以我这里一定是忽略了一些简单的东西,但我就是找不到。我认为基类函数应该由派生类继承,除非它们被声明为虚拟然后在派生类中被覆盖(但这里不是这种情况),即使派生类重载了函数名,就像我在这里所做的那样次。这不是真的吗?如果没有,除了在派生类中重新定义相同的函数之外,我还能做些什么优雅的事情来解决这个问题?

非常感谢您的帮助。

【问题讨论】:

标签: c++ class inheritance


【解决方案1】:

您必须在派生类中添加using getX;,或者在函数中使用particle::getX

标准规定,如果派生类具有同名函数,则不会自动使用基类的函数——即使派生类的函数不适合。这是为了防止错误。

您必须告诉派生类它将使用基类的函数(通过using getX; direvtive)或显式调用基类的函数(通过调用particle::getX(...)

【讨论】:

    【解决方案2】:

    基类中函数getX的声明是:

    virtual vector<double> getX(const double theta, double Real phi);
    

    定义是:

    vector<double> Particle::getX(const unsigned int surfindex)
    {
        //Stuff
    }
    

    签名不匹配!更改声明,代码就可以工作了

    顺便说一句,一个向量的副本非常昂贵,请考虑使用引用更改您的设计

    【讨论】:

      【解决方案3】:

      答案是这样的: 如果基类有“n”个函数的重载版本 和 在您的派生类中,您重新定义/覆盖(更改主体)或重载(更改签名)该函数,那么您只能使用派生类中的那个版本。

      示例:

      class Base
      {
          public:
          int abc(){}
          float abc(){}
      };
      
      class Der:public Base
      {
          public:
          SomeClassObj abc(){} //int and float returning versions of abc are now hidden for Der object
      };
      

      覆盖/重定义也是如此。

      【讨论】:

      • 这是否意味着如果我重载/覆盖了同名的函数,我需要重新复制派生类中每个未更改的基类函数?这似乎可能会导致大量代码的重复。这是否表明我设计不佳?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-11
      • 2020-09-30
      • 2015-04-16
      相关资源
      最近更新 更多