4

私はlibのコードをいくつか書いていて、すべてを実行するためにデフォルトのWin32コンソールアプリケーションを試しました。すべてのクラスを完了したので、すべてをDLLに抽出したかったので、通常のマクロで適応を開始しました。

#ifdef MYLIB_EXPORTS
    #define DllExport __declspec(dllexport)
#else
    #define DllExport __declspec(dllimport)
#endif

私は次のように定義されたコードで1つのインターフェースを使用しています:

__interface DllExport ISerializable {
    void Serialize(/* ... */);
    /* some other methods */
};

そして、これは私のexeファイルでこのコードを与えている間は機能しました。DLLで、コンパイル中に次のようなエラーが発生します

error C2039: '=' : is not a member of 'MyLib::ISerializable'
error C2664: 'MyLib::DerivedClass::operator =' : cannot convert parameter 1 from 'const MyLib::ISerializable' to 'const MyLib::DerivedClass &'

ISerializable必要なメソッドを実装するために継承するすべてのクラスに対して。(std::shared_ptr<ISerializable>コードを抽象化するために数回使用しています。)ただし、に変更__interfaceclassてすべてのメソッドを純粋な仮想にする場合、このエラーは発生せず、コンパイルは成功します。

なぜこのエラーが発生するのですか?DLLのクラス/インターフェイスに代入演算子が必要なのはなぜですか?回避策はありますか?

(C++11を使用するWindows8RTMでVisualStudio2012 RTMを使用します。)


このエラーが発生する1つのセグメントを次に示します(エラーは常に}クラスの最後を指します)。

class DllExport Tile final : public ISerializable {
public:
    __declspec(property(get=GetIsPassable, put=SetIsPassable))
    bool IsPassable;
    __declspec(property(get=GetTileId, put=SetTileId))
    uint16_t TileId;

    bool& GetIsPassable() { return this->_IsPassable; }
    void SetIsPassable(bool val) { this->_IsPassable = val; }
    uint16_t& GetTileId() { return this->_TileId; }
    void SetTileId(uint16_t val) { this->_TileId = val; }

    bool _IsPassable;
    uint16_t _TileId;

    void Serialize(OutputFileStream& ofs);
    size_t TellSize();
    size_t Unserialize(InputFileStream& ifs, size_t metadata = 0);
};

Tileこのエラーは、を使用するクラスのように、プロパティがあるクラスでも発生しますstd::shared_ptr<ISerializable>

4

1 に答える 1

1

インターフェイスには、コンパイラによって生成されたコピーコンストラクタや代入演算子がないと思います。

考えられる解決策の1つは、を明示的に実装することDerivedClass::operator=です。これは、コンパイラで生成されたバージョンがISerializable::operator=、存在しないを呼び出そうとするためです。コピーコンストラクターについても同じです。

別の解決策は、すべてのクラスをCOMクラスにすることです:)


Tileクラスの使用:

class DllExport Tile final : public ISerializable { 
public: 
    Tile(const Tile& tile) :
        _IsPassable(tile._IsPassable), _TileId(tile._TileId)
    {
    }

    /* New Code START */
    Tile& operator=(const Tile& tile)
    {
        _IsPassable = tile._IsPassable;
        _TileId = tile._TileId;
        return *this;
    }
    /* New Code END */

    __declspec(property(get=GetIsPassable, put=SetIsPassable)) 
    bool IsPassable; 
    __declspec(property(get=GetTileId, put=SetTileId)) 
    uint16_t TileId; 

    bool& GetIsPassable() { return this->_IsPassable; } 
    void SetIsPassable(bool val) { this->_IsPassable = val; } 
    uint16_t& GetTileId() { return this->_TileId; } 
    void SetTileId(uint16_t val) { this->_TileId = val; } 

    bool _IsPassable; 
    uint16_t _TileId; 

    void Serialize(OutputFileStream& ofs); 
    size_t TellSize(); 
    size_t Unserialize(InputFileStream& ifs, size_t metadata = 0); 
}; 
于 2012-09-16T21:37:44.497 に答える