構造体とその構造体に関連する関数を C++ クラスにまとめています。
class Surface
{
public:
operator SDL_Surface* () { return this->surf_; } // good idea?
private:
SDL_Surface* surf_;
}
この場合、変換演算子を使用するのは良い考えですか? それとも、問題が発生しますか? 代替案はありますか?
構造体とその構造体に関連する関数を C++ クラスにまとめています。
class Surface
{
public:
operator SDL_Surface* () { return this->surf_; } // good idea?
private:
SDL_Surface* surf_;
}
この場合、変換演算子を使用するのは良い考えですか? それとも、問題が発生しますか? 代替案はありますか?
それはひどく悪い考えです。はSDL_Surface*
クラス内に完全にカプセル化されたままにして、SDL 抽象化の一部である他のクラスからのみアクセスできるようにする必要があります。さらに、それが安全に破壊されることを保証するために、それを賢く指し示す必要があります。
明示的は良いですが、暗黙的は悪いです。
標準ライブラリの例:をに変換するstd::string
にchar const*
は、を呼び出す必要がありますc_str()
。これにより、変換が含まれていることに気付かないような不幸なことをする必要がなくなり、関数のオーバーロードによる驚くべき結果を防ぐことができます。
経験則として、このルールには例外があります。それは思考の代わりになるべきではありません。ただし、一般に、変換を暗黙的に行うには、非常に適切な理由が必要です。
カスタムデリータとして使用することをお勧めしstd::shared_ptr<SDL_Surface>
ます。SDL_FreeSurface
場合によります。
サーフェスが SDL_Surface の拡張として意図されていて、SDL_Surface が関与するすべての操作/関数に参加する必要がある場合は、「基本」要素を公開する方法が必要になるでしょう。
ただし、クラス (式で間接レベルが異なるもの) からポインターを返す代わりに、参照またはコスト参照、またはその両方を返す方がよいでしょう。
class Surface
{
public:
operator SDL_Surface& () { return *surf_; }
operator const SDL_Surface& () const { return *surf_; }
private:
SDL_Surface* surf_;
}
(注: C# っぽい Java スタイルは避けてくださいthis->xxxx
...)
あなたのSurfaceがSDL_Surfaceを必要とする単なる別のものである場合、暗黙的な変換が利用可能であってはならないので、バットにはすべて別のアプリケーションドメインがあります。
注:
上記のメモでは、Surface と SDL_Surface の有効期間や所有権については何も仮定していません。どのような操作にも参加する必要があるときはいつでも、両方のオブジェクトが存在すると仮定します。誰がいつ、どのような順序でそれらを作成し、破壊するかは、すべて別の話です。参照カウント スマート ポインターを使用しても、一般的な問題は解決されないことに注意してください。所有権の方向を定義しない限り、優先するポインターを忘れることshared_ptr
は、循環参照のためにメモリ リークを発生させる良い方法です。特に Java プログラマーによくある間違いです。
話の教訓: それらのオブジェクトをどのように処理したいかを確認してから、それらを作成および削除する方法を決定し、それらを保持するために使用する「ポインター」の魔女王と、暗黙的な変換を有効にするかどうかを決定します。