皆さんこんにちは、もし可能でしたら、インクルードファイルを未公開にする実装方法について教えてください。
【未公開パターンその1】
現在、下記のようなソースコードにおいてCTestをライブラリ化したい、と考えております。
それで、このライブラリを使うアプリケーションプログラムにおいては、"test.h"をインクルードする必要がありますが、ひいては、"template.h"もインクルードする必要があります。
そこで教えていただきたいのですが、"template.h"を公開せずに済む実装方法はないでしょうか?
【未公開パターンその2】
現在、CTestBaseを含むライブラリを、"testbase.h"というインクルードファイルとともに公開しております。
そして新たに、class CTest : public CTestBaseというクラスをつくりライブラリに加えたのですが、インクルードファイル"test.h"を公開せずにCTestを利用可能な実装方法はないでしょうか?
どうぞよろしくお願いいたします。
/* template.h */
template<class T> class CTemplate
{
...
};
/* test.h */
#include "template.h"
class CTest
{
CTest<int> m_test;
...
};
/* test.cpp */
class CTest
{
CTest<int> m_test;
...
};
/* main.cpp */
#include "test.h"
int main()
{
CTest test;
...
}
クラス宣言のみして、CTestクラスではCTemplateクラスのメンバ変数を
ポインタで定義する。
例えば以下のように。
//---------- template.h -----
#include <iostream>
template< class T > class CTemplate
{
public:
void print() const { std::cout << "CTemplate" << std::endl; }
};
//---------- test.h -----
template< class T > class CTemplate; // 宣言のみ
class CTest
{
CTemplate<int>* m_test; // ポインタで持つ(実体ではもてない)
public:
CTest();
~CTest();
void print() const;
};
//---------- test.cpp -----
#include "test.h"
#include "template.h" // 実体を扱うため
CTest::CTest()
{
m_test = new CTemplate< int >();
}
CTest::~CTest()
{
delete m_test;
}
void CTest::print() const
{
m_test->print();
}
//---------- main.cpp -----
#include "test.h"
int main()
{
CTest t;
t.print();
return 0;
}
2つあったのか。。。 orz
> 【未公開パターンその2】
は無理でしょう。使う側としては、CTestが何者かわからないのではつかえませんので。
# サンプルのようにポインタメンバを持たせるなら、operator =とかも対応する必要が。
> 【未公開パターンその2】
CTestBaseが(正しく?) interface として設計され、
CTest が「リスコフの代替則」を満たすなら、
factory method で実装することで、
CTestの公開をすることなく機能を使うことはできるかと。
# そういう実装になってなければ、設計から(以下略
「The Liskov Substitution Principle:LSP」の日本語訳は
「リスコフの置換原則」じゃないと検索できないっぽい.....。
Blueさん、ありがとうございます。
できました。
Banさん、ありがとうございます。
operator =は、とりあえずASSERT(FALSE)にしておきます。
LSPは初耳で、とても勉強になりました。
忘れてました。解決しました。
> operator =は、とりあえずASSERT(FALSE)にしておきます。
コピーされて困るクラスの定石:
class foo
{
private:
foo(const foo&); // コピーコンストラクタをpublic以外にする
foo& operator =(const foo&); // コピー演算子をpublic以外にする
...
クラスの外でコピーしようとすると、上記にアクセスできずコンパイルエラー。
# 逆にコピーするときは上記内で複製などする必要アリ。
ツイート | ![]() |