0

次の 3 つのクラスがあるとします。

class Animal {};

class Human : public Animal {};

class Dog : public Animal
{
public:
   void setOwner(Animal* owner) { this->owner = owner; }
private:
   Animal* owner;
};

以下が許可されているのはなぜですか。また、正確には何が起こっているのですか?

Dog d;
Human h;

d.setOwner(&h); // ?

最初はこのようにキャストしようとしたd.setOwner(&(Animal)h)のですが、コンパイラから警告が出て、実行時エラーになってしまいました。

編集:コンパイラが私に与えた警告は「一時的なアドレスを取得しています」でした。これはなぜですか?

4

3 に答える 3

1

他の人が指摘したように、派生*をベース*にキャストする必要はありません

しかし、誰も警告に対する質問に答えませんでした。はい、作成された一時的な動物がありました。ポインターをキャストする代わりに、オブジェクト自体を人間の所有者から動物にキャストしました。これにより、一時的な動物が人間の所有者から作成されました。このテンポラリのアドレスが set 関数に渡されました。セッターが一時的な人間の消失を返すと、かわいそうな犬の所有者ポインターが無効になります。

そのため、常に警告をお読みください。それらを理解していない場合は、エラーと見なしてください。

別の問題 - コンストラクター要素とメンバーが同じ名前を持つことを避けてください。そうしないと、いつかこのルールを難しい方法で学ぶことになります。

于 2012-12-01T17:09:18.707 に答える
1

型キャストはありませんが、Human is-an Animalです。したがって、 で動作するインターフェースはすべてAnimal*を受け入れますHuman*Animal&とについても同様Human&です。もちろん、Animalオブジェクトのインターフェースの一部しか見えません。

于 2012-12-01T10:30:28.190 に答える
1

ここで d.setOwner((Animal)&h)

ポインター型をオブジェクト型にケース化しようとしています。これはできません。

Animal クラスへのキャストの正しい方法は

d.setOwner((Animal*)&h)

でもあなたは

これ

d.setOwner(&h);

C++ のポインターは、必要に応じて基本クラスに自動的にキャストされるため、機能します。Animal* への明示的な変換は必要ありません。

于 2012-12-01T10:32:18.630 に答える