找不到C ++虚函数

时间:2010-08-16 23:01:42

标签: c++ visual-studio linker virtual-method

我有一个专门用于以几种不同格式之一导入/导出数据的类。每个格式应该具有完全相同的接口,因此我将其实现为一个基类,其中包含一堆虚拟方法和每种特定格式的派生类:

#ifndef _IMPORTEXPORT_H_
#define _IMPORTEXPORT_H_

#include "stdio.h"

enum EXPORT_TYPE {
    EXPORT_INI = 1,
};

class exportfile {
public: 
    virtual ~exportfile();

    static exportfile * openExportFile(const char * file, EXPORT_TYPE type);

    virtual void startSection(int id) = 0;
    virtual void endSection() = 0;

protected:
    exportfile(const char * file);
    FILE * hFile;

};

class iniexportfile : public exportfile {
public:
    iniexportfile(const char * file) : exportfile(file) { }

    void startSection(int id);
    void endSection();
private:
    bool inSection;

};

#endif

这是基类(exportfile)和派生类之一(iniexportfile)。

这些方法的实施如下:

#include "importexport.h"

#include <exception>
#include <assert.h>

exportfile * openExportFile(const char * file, EXPORT_TYPE type) {
    switch(type) {
        case EXPORT_INI:
            return new iniexportfile(file);
        default:
            return NULL;
    }
}

exportfile::exportfile(const char * file) {

        this->hFile = fopen(file, "w");

        if(this->hFile == 0) {
            throw new std::exception("Unable to open export file");
        }
}

exportfile::~exportfile() {
    assert(this->hFile != 0);

    this->endSection();

    fclose(this->hFile);
    this->hFile = 0;
}

void iniexportfile::startSection(int id) {
    assert(this->hFile != 0);

    fprintf(this->hFile, "[%d]\r\n", id);

    this->inSection = true;
}

void iniexportfile::endSection() {
    this->inSection = false;
}

(注意,该课程显然不完整。)

最后,我有一个测试方法:

#include "importexport.h"

#include <exception>

using namespace std;

void runImportExportTest() {
    iniexportfile file("test.ini");

    file.startSection(1);

    file.endSection();
}

无论如何,这一切都很好,但是当它被链接时,链接器会抛出这个错误:

error LNK2001: unresolved external symbol "public: virtual void __thiscall exportfile::endSection(void)" (?endSection@exportfile@@UAEXXZ)   importexport.obj

当它被标记为纯虚拟时,为什么要查找exportfile::endSection()?我不知道怎么做不纯虚拟?或者,我是否被C#宠坏了,并且完全搞砸了这些虚拟功能?

顺便说一句,这是Visual Studio 2008.我想在某处可以提一下。

1 个答案:

答案 0 :(得分:2)

当这个dtor被调用时:

exportfile::~exportfile() {
    assert(this->hFile != 0);

    this->endSection();

    fclose(this->hFile);
    this->hFile = 0;
}

编译器已“解开”vtable,因此它将解析为exportfile::endSection()函数 - 它不会调用派生版本。您需要设计一种不同的清理方法。

请参阅"Never call virtual functions during construction or destruction"