【问题标题】:vtable C++ error after implementing pure virtual method实现纯虚方法后的 vtable C++ 错误
【发布时间】:2016-10-25 05:48:00
【问题描述】:

我在一个类中定义了一个纯虚函数,如下所示:

   template <typename T>
   class PositioningMethod {

   public:
       virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) = 0;
   };

并在 ParticleFilter 中实现如下:

class ParticleFilter:public PositioningMethod<T> {

           public:
               virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) {
              /*Some code and return*/
           return ApproximatePosition::from(xxxx, xxxx, xxxx());

           }
};

但出现以下错误:

    "ParticleFilter<KnownBluetoothBeacon<CartesianLocation>, RadioProximity<BluetoothBeacon>
   >::getPosition(std::__1::list<RadioProximity<BluetoothBeacon>*, std::__1::allocator<RadioProximity<BluetoothBeacon>*> >&)",    referenced from:
             vtable for RadioProximityParticleFilter in lib.a(RadioProximityParticleFilter.o)
         "ParticleFilter<KnownBluetoothBeacon<CartesianLocation>, RadioProximity<BluetoothBeacon>
   >::ParticleFilter(std::__1::list<KnownBluetoothBeacon<CartesianLocation>,    std::__1::allocator<KnownBluetoothBeacon<CartesianLocation> > >&,    double)", referenced from:
             RadioProximityParticleFilter::RadioProximityParticleFilter(std::__1::list<KnownBluetoothBeacon<CartesianLocation>,    std::__1::allocator<KnownBluetoothBeacon<CartesianLocation> > >&,    double) in lib.a(RadioProximityParticleFilter.o)
       ld: symbol(s) not found for architecture arm64

我知道 vtable 错误通常发生在非实现纯虚函数上,但在我的情况下是一样的。知道我可能错在哪里吗?

注意:我在将我的 C++ 代码与 iOS 中的目标 C 集成时遇到的上述错误。而在 C++ 中它的工作正常

下面这行导致 ViewController.mm 中的错误:

RadioProximityParticleFilter *obj = new RadioProximityParticleFilter (*asList,50);

【问题讨论】:

  • 在模板类中创建纯虚函数有什么意义?为什么不把它排除在基类之外。当您尝试在某些模板函数中使用该方法时,如果编译器找不到该方法,则编译器已经生成错误,并且如果您希望它非常大声地失败,您可以静态断言该成员在那里。 (标准中有一些关于不混合模板和虚拟的规则,虽然我不记得它们是什么......)
  • 模板函数必须在头部实现。编译器必须在使用它的地方看到函数体。我的猜测是,您将实现放入源文件中。
  • 派生自ParticleFilterRadioProximityParticleFilter 类确实实现了getPosition,因此RadioProximityParticleFilter 的vtable 中的条目引用ParticleFilter::getPosition。链接器没有找到这个函数(我不知道为什么)并产生错误。
  • @ChrisBeck 我做了一些研究,发现在类模板中使用纯虚拟是合法的。但我不明白以下链接中的以下行:stackoverflow.com/a/8919588/4225953"对于大多数标准 C++ 实现,这很好,因为当模板被实例化时,虚函数最终成为一个函数。因此,数字在翻译单元中可以知道 vtable 中所需的槽数,因此可以生成 vtable。"
  • @IgorTandetnik 我只在标题中有模板定义。你能建议你说的是哪一门课吗?然而,模板实现由使用 SFINAE 的泛型实现组成。

标签: c++ c++11


【解决方案1】:

我完成了您的代码,以便在我的 MS VS 2013 测试项目中使用它,它可以正常工作 - 这是完整列表:

#include <iostream>
#include <list>

using namespace std;

class ApproximatePosition
{
public:
    static ApproximatePosition *from( int a, int b, int c)
    {
        cout << "from called." << endl;
        return NULL;
    }
};

class ListElem{};

template <typename T>
class PositioningMethod 
{
    public:
        virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) = 0;
};

template <typename T>
class ParticleFilter :public PositioningMethod<T>
{

    public:
        virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals)
        {
            /*dummy input and return*/
            int a = 0, b = 0, c = 0;
            cout << "getPosition called." << endl;
            return ApproximatePosition::from( a, b, c );// xxxx, xxxx, xxxx());         
        }
};

int main()
{
    PositioningMethod<ListElem> *pm = new ParticleFilter<ListElem>();

    std::list<ListElem*> l;
    pm->getPosition( l );

}

输出是:

getPosition called.
from called.

【讨论】:

  • 您能否对您提供的答案进行一些解释。谢谢!
猜你喜欢
  • 2011-07-10
  • 2013-03-24
  • 2018-06-02
  • 2011-09-08
  • 1970-01-01
  • 2011-06-24
  • 2011-11-29
  • 1970-01-01
  • 2012-05-04
相关资源
最近更新 更多