用继承拆分模板代码是正确的方法吗?

时间:2015-12-10 12:25:33

标签: c++ templates inheritance header linker

目前,我正在编写一些类,所有类都继承自基类,并以某种方式丰富它。所有这些类都使用模板,以便将不同的元素作为参数(类是抽象向量类的所有变体)。所以我在一个大的.hpp文件中编写了所有代码,因为我读到将.hpp和.cpp中的代码拆分会导致链接器问题(Splitting templated C++ classes into .hpp/.cpp files--is it possible?)并且它不起作用。

所以我很想知道,因为将一切都放在一个大的.hpp文件中并不是很干净清楚,我应该拆分它吗?为了保持代码尽可能完整,我将如何分割正确的方法?我应该将子类导入基类吗?我是否必须在每个.hpp文件中转发声明所有类?拆分如何与模板交互。

如果代码是必要的,我可以添加它。如果不是,那就试着保持简短。

3 个答案:

答案 0 :(得分:3)

文件:

header.hpp
something1.ipp
something2.ipp
something3.ipp

header.hpp的内容:

#ifndef COMPANY_PROJECT_HEADER_HPP
#define COMPANY_PROJECT_HEADER_HPP 1

#include "something1.ipp"
#include "something2.ipp"
#include "something3.ipp"

#endif

容易腻。 #include只是一种“复制粘贴”操作,因此您可以按照自己喜欢的方式将文件排列在令人愉悦且易于维护的组织结构中。

所有文件都是标题,但我已将“子标题”指定为扩展名.ipp以区分它们。

答案 1 :(得分:3)

就分割代码而言,有一种模板化代码的技术,你可以将声明和定义分开,至少在视觉上(你会明白为什么我会在一瞬间做出这种区分)。所以你首先从头开始,它将只包含你的类和函数声明

<强> foo.h中

template <typename T>
T some_foo(T x);        // declaration

#include "Foo.inl"

然后为实现创建一个单独的文件。请注意,我们在标头中#include这个.inl文件,因此就编译器而言,标题中仍然存在所有代码。这样做只适合人类读者,但这样你就可以将实际的实现代码拆分成单独的文件,并将它们包含在标题的末尾。

<强> Foo.inl

<template <typename T>
T some_foo(T x)            // definition
{
    return x + 5;
}

答案 2 :(得分:1)

  

所以我在一个大的.hpp文件中编写了所有代码,因为我读到将.hpp和.cpp中的代码拆分会导致链接器出现问题......而且它无法工作。

这只意味着你不能将函数模板的定义从它们的声明中拆分(或者从模板的定义中定义类模板的成员函数)。没有理由将所有模板的定义放在一个标题中 - 您的帖子似乎暗示您已经这样做了。

  

所以我很想知道,因为在一个大的.hpp文件中包含所有内容并不是很干净清楚,我应该拆分它吗

不确定

  

我将如何以正确的方式分割

请确保将模板的定义保留在声明它们的同一文件中 - 如链接问题的答案中所述。如果您认为这很混乱,那么您可以将定义放入另一个标题中并将其包含在声明标题中。

  

我是否必须在每个.hpp文件中转发声明所有类?

仅在引用声明的标题中,但不需要完整的定义。