2010-11-23 60 views
4

私はこれを行うと、私はm_map言って警告C4251取得エクスポートクラスstlテンプレートでエクスポートされたクラス(__declspec(dllexport))を使用する方法は?

class __declspec(dllexport) myclass 
{ 
private: 
template __declspec(dllexport) class std::map<myclass*,int>;  
std::map<myclass*,int>m_map; 
//something 
};  

を使用しています:クラスのSTD ::マップ< _Kty、_Tyは> 'が使用するDLLインターフェイスを持っている必要がありますがクラスmyclassのクライアント。
これを解決する方法についてのご意見はありますか?
Atul

答えて

6

彼らがする必要があるとして、使用するあなたのDLLを使用してそのコードをファイル__declspec(dllimport)を使用してください。

したがって、特定の他の定義が設定されている場合はdllexportを使用するマクロを作成し、そうでない場合はdllimportを作成する必要があります。どこか共通ヘッダで

:含まれるヘッダ内

extern template class FOO_API Templ<MyClass, int >; 

#ifdef EXPORTING_FOO 
#define FOO_API __declspec(dllexport) 
#else 
#define FOO_API __declspec(dllimport) 
#endif 

あなたは、テンプレートをインスタンス化することができます。ここにexternを書き留めておきます。 1つのコンパイル単位内 は、このように、同じですが、にexternなしとFOO_APIなしを宣言:

template class Templ<MyClass, int >; 

これはあなたのライブラリーを使用してコードがテンプレートをインスタンス化しないことを意味しますが、あなたのライブラリ内のものを使用することになります。これは、テンプレートに仮想メンバーがある場合に特に便利です。

テンプレートが標準ライブラリまたはブーストのものであれば、あなたのコードを使用しているコードは、あなたと同じバージョンを使用しなければならないか、深刻な問題が発生する可能性があります。

独自の例では、プライベート領域に表示されていることから、ライブラリのインターフェイスからリファクタリングすることが示唆されています。理想的には、ライブラリは公開宣言以外のパブリックメソッドとメンバーのみを公開する必要があります。プライベートなコピーコンストラクタと代入は、クラスをコピー不可と割り当て不可能にするためには問題ありません。クラスのインターフェイスの一部である実装の一部ではありません(コピーや割り当てができないと言っています)。

+0

それは私が2010年にそれをやり直すために使用した方法ですが、今は実際にはすべてのプロジェクトソースに含まれていて外部ユーザーソースではなく、FOO_APIなどを定義するstdafx.hファイルなどがあります。ヘッダーは単に#ifndef FOO_APIを実行し、#pragma commment libも行います。 – CashCow

2

エクスポートされていないメンバーでクラスをエクスポートすることはできません。考えられる解決策は、Pimplイディオムを使用することです。 Pimplでは、クラスのメンバーはユーザーに知られていません。したがって、stlクラスをエクスポートする必要はありません。 http://c2.com/cgi/wiki?PimplIdiomまたはhttp://www.gamedev.net/reference/articles/article1794.asp

例:

myclass.h:

class __declspec(dllexport) myclass 
{ 
public: 
    myclass(); 
    virtual ~myclass(); 
private: 
    myclass(const myclass& other) {} 
    myclass& operator=(const myclass& rhs) {return *this;} 
    myclassImpl* m_Pimpl; 
}; 

myclass.cpp:

#include "myclass.h" 
#include "myclassImpl.h" 


myclass::myclass() 
    :m_Pimpl(new myclassImpl()) 
{} 

myclass::~myclass() { 
    delete m_Pimpl; 
} 

myclassImpl.h:

さらにPIMPLについて読んでは、以下をご確認ください
class myclassImpl { 
private: 
    std::map<myclass*,int>m_map; 
}; 
+0

@ David、このPimplイディオムを詳しく教えていただけますか? – Atul

+0

@atulは、例を使って投稿を編集しました –

+0

良いですが、デストラクタを仮想にすることにより、より多くの問題を引き起こしています。多形性が必要な場合は、それをpImplに入れてしまうので、誰もそれらから派生することはありません。また、あなたのクラスをコピー不可能にし、割り当て不可能にする必要があります。 – CashCow

2

はそれを試したことはありませんが、このリンクは、この問題に探しているように見える:あなたはヘッダに__declspec(dllexport)を使用してすべきではない http://support.microsoft.com/kb/168958

関連する問題