1

次の基本クラスを検討してください。

@interface ViewBase : UIView
@property (readonly) LayerBase *myLayer;
+ (Class)myLayerClass; // _myLayer = [[[self class] myLayerClass] new];
@end

@interface LayerBase : CALayer
@property AbstractGrid *grid;
@end

class AbstractGrid
{
public:
    int rows, columns;
    virtual someMethod() = 0;
}

Gridさまざまなセル型を使用するテンプレートクラスがAbstractGridあります (テンプレートの Objective-C クラスを作成できないため必要です)。

template <class Cell>
class Grid : public AbstractGrid
{
public:
    Cell **cells;
    virtual someMethod() {}
}

ここで、 のサブクラスのViewBasemyLayerも持つ のサブクラスを作成しLayerBase(+myLayerClassメソッドも再定義されます)、モデル クラスに別のテンプレート パラメーターを使用します。次に例を示します。

@interface AView : ViewBase
@property (readonly) ALayer *myLayer;
@end

@interface ALayer : LayerBase
@property Grid<GridCell> *grid;
@end

class GridCell
{
public:
    int row, column;
}

アプリケーションはこのアプローチで問題なく動作しますが、コンパイラは互換性のないプロパティ タイプに関する警告を表示します。

プロパティ タイプ 'ALayer *' は、'ViewBase' から継承されたタイプ 'LayerBase *' と互換性がありません
プロパティ タイプ 'Grid *' は、'LayerBase' から継承されたタイプ 'AbstractGrid *' と互換性がありません

レイヤープロパティをタイプで宣言することにより、最初の警告を黙らせることができますがid(タイプキャストなしではドット構文を使用できず、コンパイラがキャッチできない間違いを犯す可能性があるため、これは最良の解決策ではありません):

@property (readonly) id myLayer;

C++ 型では同じことができません。gridプロパティを as と宣言してvoid *も役に立ちません。

そのような状況を処理する適切な方法はありますか?または、自分が何をしているのかを知っているので、プラグマを使用して警告を黙らせるべきですか?

C++ クラスはオプションではないため、使用しないようにアドバイスすることはご遠慮ください (将来の移植を容易にするために、クロスプラットフォーム モデル クラスのセットを作成しています)。

4

2 に答える 2

1

はい。戻り値の型を変更しないでください。例えば:

@interface LayerBase : CALayer
- (AbstractGrid *)grid;
@end


@interface ALayer : LayerBase

// ALayer's local storage and typed interface:
@property Grid<GridCell>* grid_GridCell; // << use unique selector names

// ALayer's abstract interface/overrides:
- (AbstractGrid *)grid; // << returns self.grid_GridCell

@end
于 2013-09-26T18:00:35.443 に答える