【发布时间】:2017-07-12 20:04:25
【问题描述】:
考虑下一个 c++ 代码片段
1.在 EXE 中:
Base.hpp
#ifndef _BASE_H_
#define _BASE_H_
class Base
{
public:
Base(){};
virtual double Add(double &x, double &y) = 0;
};
#endif
main.cpp
#include <iostream>
#include "Base.hpp"
#include "DerivedFactory.hpp"
void main()
{
Base *theBase = DerivedFactory::Create();
double x = 4.9, y = 3.3,z;
z = theBase->Add(x, y);//Works when Add is pure virtual function, but how???
//Linker error when Add is not pure virtual
}
2。在隐式链接的 DLL 中
Derived.hpp
#ifndef _DERIVED_H_
#define _DERIVED_H_
#include "Base.hpp"
class Derived : public Base
{
public:
double Add(double &x, double &y);
};
#endif
DerivedFactory.hpp
#ifndef _DERIVEDFACTORY_H_
#define _DERIVEDFACTORY_H_
#include "Derived.hpp"
class DerivedFactory
{
public:
__declspec(dllexport) static Derived* Create();
};
#endif
Derived.cpp
#include "Derived.hpp"
double Derived::Add(double &x, double &y)
{
return x + y;
}
DerivedFactory.cpp
#include "DerivedFactory.hpp"
Derived* DerivedFactory::Create()
{
Derived* theDerived = new Derived;
return theDerived;
}
主要问题是,当唯一导出的函数是 Create() 时,exe 如何“知道”从 dll 中正确执行 Add?
当 Add() 是“只是”虚拟而不是纯虚拟时,为什么会出现链接器错误?
【问题讨论】:
-
另外说明,以下划线开头后跟大写字母的名称(
_BASE_H_、_DERIVED_H_、_DERIVED_FACTORY_H_)和包含两个连续下划线的名称保留供执行。不要在你的代码中使用它们。 -
另外,将 Base 析构函数设为虚拟或受保护。使用非虚析构函数,对Base指针调用delete是UB;受保护时,会阻止调用 delete 并且您可能有一个单独的销毁方法(这更好,因为 DLL 和 EXE 可能有不同的堆)。