色々あってDTKを触っています。
とりあえずSpriteBatchを包んでオレオレクラス作ろうと思い、
以下のようなコードを書いていたところコンパイルエラーに。
class Sprite { private: std::unique_ptr sprite; public: explicit Sprite(wchar_t* _url) { //初期化 } ~Sprite(){} }
> error C2280: 'std::unique_ptr<Sprite,std::default_delete>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete> )' : 削除された関数を参照しようとしています
しばらく悩んでいましたが、何やっても原因が分からないので、サークルメンバーに泣きついたところサクッと解決。
デフォルトコピーコンストラクタで、spriteがコピーされているのが原因かもと言われたので、
コピーコンストラクタをこっちで定義してやることに。
class Sprite { private: std::unique_ptr sprite; public: explicit Sprite(wchar_t* _url) { //初期化 } Sprite(const Sprite& o) { } ~Sprite(){} }
これで通りました。なるほどなあって感じです。
ちなみに、SpriteBatchのヘッダを見ると、コピー防止の為にコピーコンストラクタとoperator =が削除されていました。
コピー防止をする際は注意が必要ですね。気をつけます。
==
というわけで、SyntaxHighlightのテストも兼ねた備忘録でした。
こっちの方も増やしていきたいですね……
==
2017-06/27 public忘れ修正
2017-05/07 追記
未だにアクセスされる上に内容があやふやなので調べ直して追記。 あれから一杯お勉強しました。
代入演算子のオーバーロードを削除したクラスを所持するだけで、コンパイラは所持しているクラスの代入演算子も明示的に指定していない場合、削除する模様。
class Hoge { public: Hoge operator= (Hoge const) = delete; }; class Sprite{ public: Hoge hoge; }; int main(int argc, const char* argv[]) { Sprite sprite; sprite = Sprite(); //error return 0; }
追記前は確かvs2013を使用していましたが、vs2017だとコンパイル時により詳細なメッセージを出力していました。(vs2013でも出てたのかな……?)
> error C2280: ‘Sprite &Sprite::operator =(const Sprite &)’: 削除された関数を参照しようとしています
> note: コンパイラが ‘Sprite::operator =’ をここに生成しました。
> note: ‘Sprite &Sprite::operator =(const Sprite &)’: 関数は、削除済みの、またはアクセスできない関数 ‘<不明>’ を <不明> が起動するため、暗黙的に削除されました
> note: ‘Hoge &Hoge::operator =(const Hoge &)’: 関数は明示的に削除されました
全てコンパイラメッセージの通りですが、要はコンパイル時にSpriteの代入演算子を暗黙的に生成しようとするものの、
class Sprite{ public: Hoge hoge; Sprite& operator=(const Sprite& o){ //暗黙的に生成される hoge = o.hoge; //しかしこれが出来ない } };
Hogeは代入不可なのでコンパイラはSpriteの代入演算子もdeleteにしてしまい、結果としてmainのsprite = Sprite()がエラーとなります。
class Sprite{ public: Hoge hoge; Sprite& operator=(const Sprite& o) = delete; //Hogeが代入できないので最終的にはこうなる };
解決策としては
1. Spriteをコピーして使わない
2. Spriteに代入演算子を明示的に定義
3. Hogeの代入を許可する
そもそも設計が間違っているような…… わざわざコピー禁止にしているものをコピーしようとしているわけですし。