1

考虑以下分布在 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 ,除非他们明确使用. 通常,这将通过包含in来完成。但是,这是不可能的,因为Foo是一个模板类,我不能将它的定义与它的声明分开。显式模板实例化不是一个选项。 #include "secret.h"secret.hfoo.cpp

最终,我想知道这是否可以通过显式模板实例化以外的方式实现,如果可以,如何实现?谢谢!

4

2 回答 2

1

在您提到的所有这些条件下,这是不可能的,因为写作 #include "foo.h"意味着您也隐含地写作#include "secret.h"(意味着,它的所有内容)。

你可以使用命名空间details来限制类名的可见性:

// secret.h
#pragma once

namespace details
{
   class Secret { /* ... */ };
}

然后写details::Secret在你使用它的任何地方。

不要写using namespace details;,甚至不要using details::Secret;

于 2011-11-10T18:38:02.730 回答
1

所以感谢@Mooing Duck 的提示,我想我得到了答案。我正在考虑通过创建一个新类来解决这个问题,该类充当不依赖于模板参数的Secret的瘦包装器。此类将与Foo成为朋友并提供对Secret的受保护访问,从而允许Foo访问Secret而不会通过包含 将Secret暴露给公共用户"foo.h"

一旦我编写并编译它并确保它有效,我将用实际的代码片段更新这个答案。

于 2011-11-10T19:11:30.840 回答