我对模板类有疑问。
例如,上这个类

template<class TBase> class CTemplateInherit : public TBase
{
public:

    virtual void DoNonSpecializedWork();
    virtual void DoTemplateWork();
    virtual ~CTemplateInherit();
};

// In header file
template<class TBase>
bool CTemplateInherit<TBase>::DoTemplateWork()
{
    std::wcout << L"CTemplateInherit::DoTemplateWork" << std::endl;
    TBase::DoWork();
    return true;
}

// In CPP file
bool CTemplateInherit::DoNonSpecializedWork()
{
    std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
    return true;
}

现在,我希望能够使用dllexport在CPP文件中定义非专业方法,而只需在标题中保留专业名称即可。
通常,我想我可以将成员方法定义为模板,但是由于我是从TBase继承而来的,因此不可能。

那么我将如何拆分呢?我只重写了TBase的4种方法,并且希望能够将其他40种左右的方法作为DLLEXPORT保留在DLL中,而专门化方法则放在头文件中。

预先感谢您的建议!

最佳答案

我认为缺少一条重要的信息:非专业方法是否会覆盖TBase类的虚拟方法?这是这里的中心问题。

如果不是,则可以为非专用方法创建另一个类,并从CTemplateInherit类的两个类中(公开地)继承。问题解决了。

但是,如果非专用方法覆盖了TBase类的虚方法,那么它只会稍微复杂一点:

解决方案1)采取所有非专门功能并将其重新组合为一个“详细信息” header 。作为一组(非模板)自由功能(如果很容易将输入输出作为参数传递)或作为(非模板)类以及所需的非专用数据成员。然后,在相应的cpp文件中定义所有这些功能(实现它们)(稍后将其编译到DLL中)。

然后,在CTemplateInherit类模板中,只需将非特化的函数调用转发到“详细”函数集即可。因为默认情况下内联模板,所以开销为零。如果需要将“详细信息”功能重新分组为一个类(非模板),则只需使用private继承即可,以防止功能名冲突。然后,您可以像访问其他任何继承的数据成员一样访问“详细信息”类的数据成员,并且可以将非专门的函数调用转发到“详细信息”类实现,您可以将该实现编译为DLL(如果有从DLL导出类的合适框架(因为普通的C++没有可靠的机制),但是您的问题似乎暗示您确实这样做)。

该解决方案的唯一问题是烦人的几个简单转发功能的创建。但是恕我直言,这是在DLL中添加实现的合理价格(几乎在任何时候想要这样做,最终都会编写大量包装函数)。

解决方案2)如果基类中存在一组非专业的虚函数,则该子集肯定不依赖于TBase的实际类型(我的意思是,这些函数的原型(prototype)可以在没有它的情况下形成)。然后,这意味着您可以将该函数的子集重新组合到另一个TBase将从其继承的基类中。我们称它为TNonSpecialBase。此时,您可以设置以下层次结构:

class TNonSpecialBase {
  // set of pure-virtual functions that are not special.
};

// this is an example of a class that could act as a TBase:
class TExampleBase : public virtual TNonSpecialBase {
  // set of virtual functions that are special to TExampleBase.
};

class CNonSpecialDerived : public virtual TNonSpecialBase {
  // declaration of non-specialized functions that override the function in TNonSpecialBase.
};

template <typename TBase>
class CTemplateInherit : public TBase, public CNonSpecialDerived {
  // set of virtual functions that are specialized for the template argument TBase.
};

通过上述设置,专用功能必须以CTemplateInherit的头文件结尾,但是可以将CNonSpecialDerived中重新组合的非专用功能定义在单独的cpp文件中(并编译为DLL)。这里的魔术是使用虚拟继承来允许最终类为基类TNonSpecialBase拥有单个虚拟表。换句话说,这允许类CNonSpecialDerived覆盖TBase中从TNonSpecialBase继承的虚拟函数,只要TBase不覆盖任何这些函数(在这种情况下,编译器将其称为歧义的)。这样,用户可以处理指向TBase对象的指针,调用其任何虚拟函数,这将导致对CTemplateInherit实现(专用)或CNonSpecialDerived实现(可能在DLL中)的调度。

10-08 11:51