0

編集:コードはどれも私のものではなく、すべて私に与えられたものであり、オブジェクト割り当てメソッドの観点から分析しているだけです。

私はメモリ割り当てに本当に苦労しています。過去5時間にここで100の例を見てきたことをお約束します。これはおそらく言葉遣いが悪いことを理解しており、事前にお詫び申し上げます。

1.)バージョン2がクラスBの代わりにクラスAのf()を出力する理由がわかりません。この線

A* objA1 = objB;

タイプAのオブジェクトを指すポインタobjA1を宣言し、そのアドレスをobjBが指している場所B(2,3)に割り当てています。「ヒープダイナミックオブジェクトの場合は、b1をa1に割り当てることができます」という文を読みました。objA1-> f()を呼び出すとき、私は単にこの場所に行くと言っているのですか、ああ、Bを見つけましたか?それをAにキャストし、f()を呼び出します。

2.)バージョン1のスライスされたobjBを考えたのは、Aのスペースが割り当てられたこのオブジェクトを、大きい方のBに等しく設定すると言っているからです。しかし、私がcout << objB.bf; この割り当ての後、それはまだ有効です。はAobjA1= objB; objA1を静的に宣言していませんか?そしてもう一度、なぜこれはBのf()を出力しないのでしょうか?

3.)2つのobjA1割り当ての違いは何ですか?どの機能が2つのうちの1つでのみ機能するかと同じです。ある種の古い分類を与えたい場合は、両方を「ヒープダイナミック」と呼ぶことができますか?

class A {
  private:
    int a;
  public:
    A(int ia) {a = ia;}
    void f() { 
      cout << "Call to method f defined in class A" << endl;
    }
};
 class B : public A {
  private:
    int b;
  public:
    B(int ia, int ib) : A(ia) {b = ib;}
    void f() { 
      cout << "Call to method f specialized in class B" << endl; 
    }
    void bf() { 
      cout << "Call to class B own method bf" << endl; 
    }
}; 
// C++ driver - Version 1
void main() { 
  A objA = A(1);
  B objB = B(2,3);

  objA.f();
  objB.f();
  objB.bf(); 

  A objA1 = objB;
  objA1.f();
}

 // C++ driver - Version 2
void main() {
  A* objA = new A(1);
  B* objB = new B(2,3);

  objA->f();
  objB->f();
  objB->bf(); 
  A* objA1 = objB;
  objA1->f();
} 
4

2 に答える 2

2

virtual基本クラスのように(baseへのポインタを介して)多態的に呼び出される関数を宣言する必要があります。virtualコンパイラは、オブジェクトへのポインタ(または参照)を介して関数の呼び出しに遭遇すると、静的タイプではなく、オブジェクトの動的タイプを関数で検索します。したがって、関数定義の前に固執するだけです。virtualA

virtual void f() { 
  cout << "Call to method f defined in class A" << endl;
}

あなたの行A objA1 = objB;は確かにあなたのオブジェクトをスライスし、その一部をにBコピーするだけです。でのみのメンバー関数を呼び出すことができます。ただし、それでも以前と同じオブジェクトです。これはまだであり、のすべてのメンバー関数を使用できます。喜んで電話することはできますが、電話することもできません。AobjA1AobjA1objBBBobjB->bf()objA->bf()objA1->bf()

疑わしい場合は、関数を呼び出しているオブジェクトのタイプを確認してください。の場合は、の関数Aのみを呼び出すことができます。A同様にB。ポインターを介してアクセスして関数を呼び出す場合は、オブジェクトのにvirtual属する関数が呼び出されます(ポインター指しているタイプではなく)。dynamic type

于 2012-12-07T17:54:32.623 に答える
1

C ++は、デフォルトでは動的ディスパッチを使用しません。これは、が指すインスタンスの動的タイプに関係なく、が常に呼び出すように宣言されp->f()たときに呼び出すことを意味します。動的ディスパッチを有効にするには、関数を宣言する必要があります。これは、すべてのメンバー関数が暗黙的にであるJava / C#とは対照的です。pX *pX::f()pvirtualvirtual

「バージョン1」でのスライスは実際に発生しますが、objBどこかに割り当てられても影響はありません。それobjAはスライスの影響を受けます(つまり、の一部でobjBはない部分を無視しAます)。

于 2012-12-07T17:55:49.840 に答える