C++编程思想 第1卷 第15章 多态性和虚函数 继承和VTABLE 对象切片

当多态地处理对象时,传地址与传值有明显的不同

如果对一个对象进行向上类型转换,而不使用地址或引用,发生的事情将会
使我们吃惊:这个对象被“切片”,直到剩下来的是适合于目的地子对象

//: C15:ObjectSlicing.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#include <iostream>
#include <string>
using namespace std;

class Pet {
  string pname;
public:
  Pet(const string& name) : pname(name) {}
  virtual string name() const { return pname; }
  virtual string description() const {
    return "This is " + pname;
  }
};

class Dog : public Pet {
  string favoriteActivity;
public:
  Dog(const string& name, const string& activity)
    : Pet(name), favoriteActivity(activity) {}
  string description() const {
    return Pet::name() + " likes to " +
      favoriteActivity;
  }
};

void describe(Pet p) { // Slices the object
  cout << p.description() << endl;
}

int main() {
  Pet p("Alfred");
  Dog d("Fluffy", "sleep");
  describe(p);
  describe(d);
  getchar();
} ///:~

函数describe()通过传值方式传递一个类型为Pet的对象
然后对于这个Pet对象调用虚函数description()

按值传递时,Pet对象的拷贝构造函数被调用,该构造函数初始化VPTR指向
Pet的VTABLE,并且只拷贝这个对象的Pet部分

对象切片实际上是当它拷贝到一个新的对象时,去掉原来对象的一部分,而
不是像使用指针或引用那样简单地改变地址的内容

输出
This is Alfred
This is Fluffy

猜你喜欢

转载自blog.csdn.net/eyetired/article/details/81351878