代码之家  ›  专栏  ›  技术社区  ›  Mike Caron

找不到C++虚拟函数

  •  1
  • Mike Caron  · 技术社区  · 14 年前

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

    #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#宠坏了,完全把这些虚拟函数搞砸了?

    顺便说一下,这是VisualStudio2008。我想我应该在什么地方提一下。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Michael Burr    14 年前

    当调用此dtor时:

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

    exportfile::endSection() 函数-它不会调用派生版本。你需要设计一个不同的清理方法。

    看到了吗 "Never call virtual functions during construction or destruction" .