模板类中实现的分离
Separation of implementation in template classes
我有以下问题:
假设存在一个基类CCD_ 1。
这个类有很大一部分总是一样的。小部件应该是通用的,例如具有模板参数T
。
目前,我不想创建A
的模板类,因为我不想在头文件中有大型非通用部件实现。我能用它做什么?我有没有可能实现与类头分离的大的非泛型部分,但也有小的泛型部分作为某种模板?
举个例子:假设您有一个通用树,它有一些模板函数(如add(T o)
),但许多函数不依赖于模板(如size()
,但更复杂)。
作为补充:A
有多个子类,这些子类应该决定T
的最终类型…
我知道编译器无法处理cpp文件中模板的实现。但是,有没有一种概念上的方法来解决分离?例如,与模板不同的东西?
直接处理分离的一种方法是将模板拆分为两个头文件(这与将非模板内容拆分为.h
声明和.cpp
实现的方式非常相似)。
然后,您可以在模板上使用显式模板实例化。
// tree.h
// Included by anything that needs to use the tree template.
template <typename T> class tree {
void inline_func() { }
void noninline_func();
};
// tree_impl.h
// This header is only included by a single .cpp file: the
// template repository module that contains instantiations.
template <typename T> tree<T>::noninline_func()
{
}
// template-repo.cpp
#include "tree.h"
#include "tree_impl.h" // only template-repo.cpp includes this!
// same for all other templates
#include "mytype.h"
#include "othertype.h"
template class tree<mytype>; // instantiate template here over mytype
template class tree<othertype>; // ditto over othertype
// ... other instantiations
您可以使用预处理器将两个头文件滚动在一起:
// tree.h
template <typename T> class tree {
void inline_func() { }
void noninline_func();
};
#ifdef INSTANTIATING_TEMPLATES
template <typename T> tree<T>::noninline_func()
{
}
#endif
// template-repo-cpp
#define INSTANTIATING_TEMPLATES
#include "tree.h"
#include "mytype.h"
template class tree<mytype>;
然而,这种轻微的便利意味着,当你在任何地方A
0时,你会通过预处理器传递很多额外的cruft。
这一切都有缺点,就像C++一样。它不仅是手动维护,而且每次您触摸模板头或用作模板参数的某个类型时,都必须重新编译整个template-repo.cpp
。(当然,事情可以分为多个迷你回购:解决解决方法问题的对策)。
但是,难道没有一种概念性的方法来解决分离吗?例如与模板不同的东西?
如果你正在寻找一种可移植的c++替代模板,那么它们根本无法提供模板所能提供的强大功能。除此之外,让我们试着解决你的问题。
您可以简单地将函数打包到一个单独的类中,该类可以在任何其他头中实现。我们有两种选择,一种是将代理类作为基类的成员添加,另一种是使用继承。
选择A(直接包括作为会员)
使用这种方法你会遇到一个问题,他们无法直接访问函数。不能使.
运算符过载!处理此问题的一种方法是使用代理函数,该函数只返回对成员变量的引用。下面是一个最小的工作示例:
#include <iostream>
using namespace std;
// forward declaration
template <typename T>
class B;
template <typename T>
class A {
public:
// allows friendship regardless of the type instantiated with class A
template <typename U>
friend class B;
A(int a) : a_(a), funcs_(this) {}
// this could be named anything
B<T>& utils() { return funcs_; }
private:
int a_;
// proxy class instance, should probably be static
B<T> funcs_;
};
// this class could be modifed to accept any type but i did this for simplicity
template <typename T>
class B {
public:
explicit B(A<T>* base) : base_(base) {}
// function implementations go here...
void print() { std::cout << base_->a_; }
private:
A<T>* base_;
};
int main() {
A<int> testA(23);
testA.utils().print();
return 0;
}
选择B(继承)
使用这种方法,您将能够直接访问函数,但这是以使用继承为代价的,我知道有些人会倾向于不使用继承而不是选择A。下面是一个工作示例:
#include <iostream>
using namespace std;
// forward declaration
template <typename T>
class B;
template <typename T>
class A : public B<T> {
public:
// allows friendship regardless of the type instantiated with class A
template <typename U>
friend class B;
A(int a) : a_(a), B(this) {}
private:
int a_;
};
// this class could be modifed to accept any type but i did this for simplicity
template <typename T>
class B {
public:
explicit B(A<T>* base) : base_(base) {}
// function implementations go here...
void print() { std::cout << base_->a_; }
private:
// pointer to base class
A<T>* base_;
};
int main() {
A<int> testA(23);
testA.print();
return 0;
}
如果是我的选择,我很可能会使用选项B,我不想让客户端显式调用一个函数,也不想调用另一个函数。很明显,您可以使用一些涉及typedef
和bind
的技巧,但我认为这会增加不必要的开销。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 将非类库分离为标头和实现的方法
- C++分离功能,实现性能优化
- 在C++中,我不能在不分离标头和 cpp 的情况下实现此类吗?
- 如何用默认模板参数分离模板类的声明和实现
- 将接口与实现分离不起作用 c++
- 无法分离实现和接口
- 模板类中实现的分离
- 如何分离模板构造函数的实现(如果类不是模板)
- C++ 模板复杂图像读取类执行时间慢,声明和实现分离
- C++模板:使用模板参数分离定义和实现
- C++生成文件,同时分离声明和实现
- 继承层次结构中接口与实现的分离(C++新手)
- C++在模板类中的友好关系,接口与实现的分离
- 一个自动分离C++头和实现的工具
- c++提倡类定义和类实现之间的分离,但JAVA没有
- 使用头/源文件来分离接口和实现