如何在基类中使用虚函数?

问题描述 投票:0回答:1

考虑以下两种结构:

struct Potential{
    virtual double energy(int full_system, int particle_id)=0;

    double energy(int full_system){
        int n_particles=100;
        double E=0.0;
        for (int particle_id=0; particle_id<n_particles; particle_id++){
            E+=energy(full_system, particle_id);
        }
        return E;
    }
};


struct MorsePotential: Potential{
    //constructor
    MorsePotential (){}

    //implementing the virtual function
    double energy(int full_system, int particle_id){
        return 10.0;
    }
};

第一个,

Potential
有两个功能,都叫
energy
。第一个是虚拟的,应该在所有子结构中实现。第二个应该由所有孩子继承。请注意,第二个调用父级中的第一个。

MorsePotential
Potential
的子级,并实现其父级的虚拟
energy
函数。但是,当使用
MorsePotential
时,我收到编译错误。代码如下:

MorsePotential mpotential;
std::cout<<mpotential.energy(0,0)<<std::endl; //works
std::cout<<mpotential.energy(0)<<std::endl; //gives compiler error

给出错误:

inherit.cc: In function ‘int main()’:
inherit.cc:35:32: error: no matching function for call to ‘MorsePotential::energy(int)’
   35 |  std::cout<<mpotential.energy(0)<<std::endl;
      |                                ^
inherit.cc:25:9: note: candidate: ‘virtual double MorsePotential::energy(int, int)’
   25 |  double energy(int full_system, int particle_id){
      |         ^~~~~~
inherit.cc:25:9: note:   candidate expects 2 arguments, 1 provided

我很困惑,因为第一行编译了,我可以调用

mpotential.energy(0,0)
,即虚函数的实现。然而,子级无法找到
mpotential.energy(0)
,即在其父类中实现的函数。

我想知道是什么原因导致这个错误?一开始我以为父类中可能不允许调用虚函数,但是定义

MorsePotential mpotential;
编译所以好像可以实例化子类。

c++ c++11 inheritance virtual-functions
1个回答
0
投票

这就是名称查找的工作原理。名称查找不考虑参数。它只查找被调用函数的名称。您调用

energy
,找到
MorsePotential::energy
,在考虑基类范围之前停止名称查找。

您可以通过 using 声明将名称从基类拉到派生类范围:

struct MorsePotential: Potential{

    using Potential::energy;   // <-------

    //implementing the virtual function
    double energy(int full_system, int particle_id){
        return 10.0;
    }
}; 

(您不应实现与编译器生成的构造函数具有相同功能的构造函数。)

请注意,如果您通过引用使用实际的多态性,则不会出现问题:

 void foo(Potential& p) {
      p.energy(42);    // OK, also with your code
 }
© www.soinside.com 2019 - 2024. All rights reserved.