多态性与虚函数之对象切片

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

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)
{
    cout<<p.description()<<endl;
}

void newdescribe(Pet* p)
{
    cout<<p->description()<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    Pet p("Alfred");
    Dog d("Fluffy", "sleep");
    describe(p);
    describe(d);
    newdescribe(&p);
    newdescribe(&d);
    system("pause");
    return 0;
}
//this is Alfred
//this is Fluffy
//this is Alfred
//Fluffy likes to sleep

结论:

  第一,describe()接受的是一个Pet对象而不是指针或引用),所以describe()中的任何调用都将引起一个与Pet大小相同的对象压栈并在调用后清除。这意味着,如果一个有Pet派生来的类的对象被传给describe(),则编译器会接受它,但只拷贝这个对象的对应于Pet的部分,切除这个对象的派生部分

Dog对象d在切片过程中真的变成了一个Pet对象。

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

posted @ 2013-05-21 10:09  wiessharling  阅读(231)  评论(0)    收藏  举报