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;
}

したがって、私の問題は、明示的に使用しない限り、 SecretをFoo のユーザーから隠したいということです。通常、これはinを含めることによって行われます。ただし、Fooはテンプレート クラスであり、その定義を宣言から分離できないため、これは不可能です。明示的なテンプレートのインスタンス化はオプションではありません。#include "secret.h"secret.hfoo.cpp

最終的に、明示的なテンプレートのインスタンス化以外の方法でこれが可能かどうかを知りたいです。ありがとう!

4

2 に答える 2

1

@Mooing Duckのヒントのおかげで、私は答えを得たと思います。テンプレートパラメータに依存しないSecretのシンラッパーとして機能する新しいクラスを作成することで、これを解決することを検討しています。このクラスはFooと友達になり、シークレットへの保護されたアクセスを提供します。これにより、Fooは、を含めることでシークレットをパブリックユーザーに公開せずにシークレットにアクセスできます。"foo.h"

この回答を作成してコンパイルし、機能することを確認したら、実際のコードスニペットでこの回答を更新します。

于 2011-11-10T19:11:30.840 に答える
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 に答える