[英]Templated classes with pimpl idiom incorrect
如在MSDN库中描述这里我想尝试一点与PIMPL方法。 现在我有一个Foo.hpp
template<typename T>
class Foo {
public:
typedef std::shared_ptr<Foo<T>> Ptr;
Foo();
private:
class Impl;
std::unique_ptr<Impl> pImpl;
};
其中T
参数还没有使用。 实现存储在Foo.cpp
template<typename T>
class Foo<T>::Impl {
public:
int m_TestVar;
};
template<typename T>
Foo<T>::Foo() : pImpl(new Impl) {
this->pImpl->m_TestVar = 0x3713;
}
目前编译器有两个错误和一个警告:
use of undefined type 'Foo<T>::Impl'; ... vc\\include\\memory in line 1150
can't delete an incomplete type; ... vc\\include\\memory in line 1151
deletion of pointer to incomplete type 'Foo<T>::Impl'; no destructor called; ... vc\\include\\memory in line 1152
这里有什么问题,我怎么解决?
编辑。 删除了对std::make_shared
的调用 - 基于一个旧版本复制和粘贴失败。
我有一个类似的问题 - 我们在我们的系统中有一个名为NamedComponent
的基类,我想创建一个模板,它接受一个现有的命名组件并将其转换为pimpl外观。
我所做的是将模板分成标题和内联文件,并创建一个函数以使模板实例化。 这允许实现在库中,具有该实现的外观的模板实例,并且客户端能够基于模板和实现的前向声明来使用外观。
标题'Foo.h':
template<class T> class Foo
{
public:
Foo ();
virtual ~Foo();
private:
T *impl_;
public:
// forwarding functions
void DoIt();
};
内联函数'Foo.inl':
#include "Foo.h"
template<class T> Foo<T>::Foo() :
impl_ ( new T )
{
}
template<class T> Foo<T>::~Foo()
{
delete impl_;
}
// forwarding functions
template<class T> void Foo<T>::DoIt()
{
impl_ -> DoIt();
}
// force instantiation
template<typename T>
void InstantiateFoo()
{
Foo<T> foo;
foo.DoIt();
}
实现cpp文件 - 包含模板内联函数,定义实现,引用实例化函数:
#include "Foo.inl"
class ParticularImpl {
public:
void DoIt() {
std::cout << __FUNCTION__ << std::endl;
}
};
void InstantiateParticularFoo() {
InstantiateFoo<ParticularImpl>();
}
客户端cpp文件 - 包含模板头,转发声明实现并使用pimpl facade:
#include "Foo.h"
class ParticularImpl;
int main () {
Foo<ParticularImpl> bar;
bar.DoIt();
}
你可能不得不摆弄InstantiateFoo函数的内容来强制编译器实例化所有函数 - 在我的例子中,base在模板方法中调用了所有pimpl的函数,所以一旦引用了它们,它们都是。 您无需调用Instantiate函数,只需链接到它们即可。
IMHO PIMPL对模板没有多大意义,除非您知道所有可能的模板参数并且该集合相当小。 问题是,您将在头文件中具有Impl
实现,否则,如注释中所述。 如果可能的T
参数的数量很小,您仍然可以使用分隔,但是您需要在标头中声明特化,然后在源文件中显式实例化它们。
现在给编译器错误: unique_ptr<Impl>
需要的定义Impl
可用。 你需要分别在ctor Foo::Foo
和dtor Foo::~Foo
直接使用new
和delete
,而忽略了智能指针的便利性/安全性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.