3

这段代码是 Bruce Eckel 在他的书“Thinking in C++”第 14 章第 649 页中编写的。我不明白的是他在下面发表的评论 [强调添加]:

operator<<for很有趣,Child因为它在其中调用operator<< for 的方式Parent:通过将Child对象转换为 a Parent& (如果您转换为基类对象而不是引用,您通常会得到不希望的结果)

下面是对应的代码:

#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

是的,这没关系。Parent 和 Child 是多态的。作为子继承的客户,您可以将其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

不希望的结果是编译器必须创建 Child 对象的 Parent 部分的临时副本,将对该临时对象的引用传递给插入器,然后销毁该临时对象。这是很多搅动...

而且,正如@NeelBasu 暗示的那样,如果Parent有被覆盖的虚函数,Child则从插入器调用这些函数不会调用Child版本,因为传入的对象是一个Parent对象。

于 2012-08-18T19:13:09.873 回答
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 回答