对类的用户隐藏模板类使用的 #include
考虑以下分布在 3 个文件中的代码:
// secret.h
#pragma once
class Secret { /* ... */ };
// foo.h
#pragma once
#include "secret.h"
template <typename T>
class Foo {
public:
// Other members ...
void bar();
};
/* Definition is included inside 'foo.h' because Foo is a template class. */
template <typename T> void Foo<T>::bar() {
Secret s;
/* Perform stuff that depend on 'secret.h' ... */
}
// main.cpp
#include "foo.h"
int main() {
Foo<int> foo;
Secret secret; // <--- This shouldn't be allowed, but it is!
return 0;
}
所以我的问题是我想对 Foo 的用户隐藏 Secret 除非他们明确使用#include“secret.h”
。通常,这可以通过在 foo.cpp
中包含 secret.h
来完成。但是,这是不可能的,因为 Foo 是一个模板类,我无法将其定义与其声明分开。 显式模板实例化不是一个选项。
最终,我想知道除了显式模板实例化之外,这是否可以通过某种方式实现,如果可以,如何实现?谢谢!
Consider the following code spread out along 3 files:
// secret.h
#pragma once
class Secret { /* ... */ };
// foo.h
#pragma once
#include "secret.h"
template <typename T>
class Foo {
public:
// Other members ...
void bar();
};
/* Definition is included inside 'foo.h' because Foo is a template class. */
template <typename T> void Foo<T>::bar() {
Secret s;
/* Perform stuff that depend on 'secret.h' ... */
}
// main.cpp
#include "foo.h"
int main() {
Foo<int> foo;
Secret secret; // <--- This shouldn't be allowed, but it is!
return 0;
}
So my issue is that I want to hide Secret from the user of Foo unless they explicitly use #include "secret.h"
. Normally, this would be done by including secret.h
in foo.cpp
. However, this isn't possible because Foo is a template class and I cannot separate its definition from its declaration. Explicit template instantiation is not an option.
Ultimately, I want to know if this is possible in some way other than Explicit template instantiation, and if so, how? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于您提到的所有这些条件,这是不可能的,因为编写
#include "foo.h"
意味着您也隐式编写#include "secret.h"
(意味着,所有内容)。您可以使用诸如
details
之类的命名空间来限制类名称的可见性:然后在任何使用它的地方编写
details::Secret
。请勿编写
using namespace details;
,甚至请勿编写using details::Secret;
。That is not possible with all those conditions which you mentioned, because writing
#include "foo.h"
means you also implictly write#include "secret.h"
(means, all it contents).You can use namespace such as
details
to limit the visibility of the name of the class:And then write
details::Secret
wherever you use it.DO NOT write
using namespace details;
, NOT evenusing details::Secret;
.感谢@Mooing Duck 的提示,我想我得到了答案。我正在考虑通过创建一个新类来解决这个问题,该类充当 Secret 的薄包装器,不依赖于模板参数。该类将成为Foo的好友并提供对Secret的受保护访问,从而允许Foo访问Secret而不暴露 >通过包含
“foo.h”
对公共用户保密。一旦我编写并编译它并确保它有效,我将用实际的代码片段更新这个答案。
So thanks to @Mooing Duck's hint, I think I got the answer. They way I'm considering solving this by creating a new class that acts as a thin wrapper for Secret that does not rely on a template parameter. This class would friend Foo and provide protected access to Secret, thus allowing Foo to access Secret without exposing Secret to the public user through inclusion of
"foo.h"
.I will update this answer with the actual code snippet once I write and compile it and make sure that it works.