0
class A {
public:
    A(void) { cout << "A::A" << endl; }
    A(const A& a) { cout << "A::A(a)" << endl; }
    virtual ~A(void) { cout << "A::~A" << endl; }
    virtual void g(void) { cout << "A::g" << endl; }
};

class B : public A {
public:
    B(void) { cout << "B::B" << endl; }
    ~B(void) { cout << "B::~B" << endl; }
    void g(void){ cout << "B::g" << endl; }
};

void print(A c) {
    cout << "print" << endl;
}

int main(void) {
    A a;
    B b;
    A* c = &b;
    c->g();
    print(*c);
    return 0;
}

A::A(a)呼び出し時にこのステートメントが実行される理由がわかりませc->g()print(*c);

そして、メソッドの出力がプログラムのどの部分に属しているのかよくわかりませんか?

4

2 に答える 2

3

引数を値でprint関数に渡すため、コピー コンストラクターを使用してコピーを作成する必要があります。そのため、 が呼び出されたときにコピー コンストラクターが呼び出さprintれます。

call be reference (またはポインターを渡す) に変更すると、コピーは行われません。


また、他の人が述べているようにprint、「通常の」関数、「フリー」関数、または非メンバー関数とも呼ばれます。プログラムに「属し」、グローバルスコープに存在し、外部リンケージがあります。

于 2016-03-23T10:23:30.203 に答える
1

Printはメソッドではなく、関数であるため、どこにも「所属」していません。単にプログラムの一部です。関数はオブジェクト指向以前の時代のものですが、依然として重要な位置を占めています。

関数は次のvoid print(A c)ように分解できます。

  1. void、これは戻り値です。この場合は何もありません。
  2. print(、これは関数の名前です。
  3. A c)、これは、 cという名前Aの単一のパラメーターを取ることを意味します。

そのため、オブジェクト A のコピー コンストラクターA::A(const A &)は次のようになります。基本的に、このメソッドは、タイプ A のオブジェクトがタイプ A の新しいオブジェクトにコピーされるたびに呼び出されます。

を呼び出すとprint(*c)、ポインターがc参照されます。これにより、 が指すオブジェクト (つまり、 型のオブジェクト) への参照が行わcます A。これは、関数にコピー構築され、print関数によって使用される一時的なconst A &ものになります。

これが、Copy-constructor が呼び出される理由です。

于 2016-03-23T10:30:19.837 に答える