3

このコードは、Bruce Eckel が彼の著書「Thinking in C++」の第 14 章 649 ページに書いたものです。

operator<<forChildが興味深いのは、その中で for を呼び出す方法です:operator<< オブジェクトParentChildaParent& にキャストすることによって (参照の代わりに基本クラス オブジェクトにキャストすると、通常、望ましくない結果が得られます)

対応するコードは次のとおりです。

#include <iostream>
using namespace std;

class Parent
{
    int i;

    public:

    Parent(int ii) : i(ii) { cout << "Parent(int ii)\n"; }
    Parent(const Parent& b) : i(b.i) { cout << "Parent(const Parent&)\n"; }
    Parent() : i(0) { cout << "Parent()\n"; }

    friend ostream& operator<<(ostream& os, const Parent& b) { 
        return os << "Parent: " << b.i << endl; 
    }
};

class Member
{
    int i;

    public:

    Member(int ii) : i(ii) { cout << "Member(int ii)\n"; }
    Member(const Member& m) : i(m.i) { cout << "Member(const Member&)\n"; }

    friend ostream& operator<<(ostream& os, const Member& m) { 
        return os << "Member: " << m.i << endl; 
    }
};

class Child : public Parent
{
    int i;
    Member m;

    public:

    Child(int ii) : Parent(ii), i(ii), m(ii) { cout << "Child(int ii)\n"; }

    friend ostream& operator<<(ostream& os, const Child& c) { 
        return os << (Parent&)c << c.m << "Child: " << c.i << endl; 
    }
};

int main()
{
    Child c(2);
    cout << "calling copy-constructor: " << endl;
    Child c2 = c;
    cout << "values in c2:\n" << c2;
}
4

3 に答える 3

1

望ましくない結果として、コンパイラは子オブジェクトの親部分の一時コピーを作成し、その一時への参照をインサータに渡してから、一時を破棄する必要があります。それはたくさんのかき回しです...

また、@ NeedBasuが示唆しているように、Parentでオーバーライドされる仮想関数がある場合、渡されるオブジェクトはオブジェクトであるため、インサーターChildからそれらの関数を呼び出してもChildバージョンは呼び出されませんParent

于 2012-08-18T19:13:09.873 に答える
1

はい、大丈夫です。親と子はポリモーフィックです。Child&子継承のクライアントとして、にキャストできますParent&

os << (Parent&)crhs(Parent&)cは型なParent&ので、operator<<(ostream& os, const Parent& b)から呼び出されますoperator<<(ostream& os, const Child& b)

C++ ポリモーフィズムでは、参照型またはポインター型がある場合にのみ機能します

于 2012-08-18T19:01:39.853 に答える
1

それはおそらくオブジェクトのスライスを意味しています。つまり、(参照を割り当てるのではなく) 親クラスのインスタンスにオブジェクトをコピーすると、オブジェクトの一部が失われます。

この質問への回答もご覧ください。


以下に例を示します: ( http://ideone.com/qeZoaを参照)

#include <iostream>
using namespace std;

struct parent {
  virtual const char* hi() const { return "I'm your father..."; }
};

struct child : public parent {
  const char* hi() const { return "No way!"; }
};

int main() {
  child c;
  cout << ((parent) c).hi() << endl;
  cout << ((parent&)c).hi() << endl;
}
于 2012-08-18T19:52:51.723 に答える