4

インライン化されたメンバー関数のみで構成される単純なクラスを考えてみましょう。例えば:

template <typename T1, typename T2>
class Point2D {
public:
    typedef Point2D<T1,T2> ThisType;
    typedef T1 Tx;
    typedef T2 Ty;
    T1 x;
    T2 y;
    inline Point2D() : x(0), y(0) {}
    inline Point2D(T1 nx, T2 ny) : x(nx), y(ny) {}
    inline Point2D(const Point2D& b) : x(b.x), y(b.y) {}
    inline Point2D& operator=(const Point2D& b) { x=b.x; y=b.y; return *this; }
    inline ~Point2D() {}
};

typedef Point2D<int,int> Int2;

タイプのオブジェクトが、DLL にエクスポートするInt2別のクラス (たとえば、 class MyClass、 member Int2 point) 内で使用されている場合、次の警告が表示されます。

警告 C4251: 'MyClass::point': クラス 'Point2D' には、クラス 'MyClass' のクライアントが使用する dll インターフェイスが必要です

ただし、__declspec(dllexport)警告が示唆するように「Point2D」の定義を入れると(すべての関数がインライン化されているため、これはばかげているように思えますが、テンプレートであるため、SO question を参照してください)、使用しようとすると次のエラーが発生します別のプロジェクトの DLL:

エラー LNK2019: 未解決の外部シンボル "__declspec(dllimport) public: __thiscall lwin::Point2D::Point2D(int,int)" ...

の定義はPoint2D、すべてのプロジェクトで表示されるヘッダーに示されていることに注意してください。

私は何をすべきか?スキップしdllexportて警告を無視しますか? または、このコンパイラの混乱を回避できる巧妙なトリックはありますか?

4

2 に答える 2

1

この問題を解決するには、のメンバーをメンバーにInt2置き換えます。コンストラクタでインスタンスを作成し、デストラクタで削除します。MyClassInt2*Int2MyClassMyClass

テンプレート化されたクラスはエクスポートできないため、として宣言することはできません __declspec(dllexport)。Dllとそのクライアントが異なるコンパイルオプションでコンパイルされている場合、コンテナクラスのサイズが異なる可能性があるため、C4251が表示されます。これにより、未定義の動作が発生します。一方、ポインタのサイズは常に同じです。

于 2012-11-18T13:13:17.107 に答える