class Animal {
// ...
};
class Dog : extended Animal {
// ...
};
class Cat : extended Animal {
// ...
};
class DogsCompanions {
members as list<Dog>;
iterator_counter as int;
public:
push(dog as Dog) as void { members.push_back(dog); }
shift() as Dog { return members.pop_front(dog); }
};
class CatsCompanions {
// ... (似たような内容)
};
enum ANIMAL_KIND {
ANIMAL_DOG,
ANIMAL_CAT,
};
DogsCompanions dogs;
CatsCompanions cats;
getFavoriteAnimal(kind as ANIMAL_KIND) as Animal{
switch (kind){
case ANIMAL_DOG:
animal = dogs.shift;
break;
case ANIMAL_CAT:
animal = cats.shift;
break;
default:
assert(0);
animal = NULL;
break;
}
return animal;
}
さて、getFavoriteAnimal()
関数内の変数 animal
は、何の型としてコンパイルされるべきでしょう?
# そもそも、その設計は無いだろうとか言われちゃうと、ちょっとアレなんですが。。。
上記のコードで、変数 animal
を Animal
型の変数として認識するようコンパイラに要求するのはさすがに無理があるように思います (return 文を根拠に類推すれば不可能ではないですが)。だとすると、コンパイラは以下のいずれかの理由でエラーを吐くしかありません。
- 型の曖昧さを解消するよう要求するエラー : 例えば、
if
構文や switch
構文の中で使用する変数は、事前に型宣言が必要、とか。
- 最初の出現時点で
Dog
型の変数であると認識し、Cat
オブジェクトを代入しようとする箇所で型不一致エラー。
どちらにせよ、変数 animal
は事前に型宣言が必要になってしまいます。
# ついでに言うと、NULL
は本当は NULL
と書くべきではない気もするけど。
セコメントをする