c++ - 理解虚函数和指针的使用

标签 c++ polymorphism

在了解切片之后,据我所知,可以使用指向动态变量的指针来打破它。但是怎么会呢?为什么在那一点上没有切片?我想我自己,但我不确定。在 ppet = pdog; 赋值后,pdog 指向与 ppet 相同的地址。不是吗?

//Program to illustrate use of a virtual function 
//to defeat the slicing problem.

#include <string>
#include <iostream>
using namespace std;

class Pet
{
public:
    virtual void print();
    string name;    
};

class Dog : public Pet
{     
public: 
    virtual void print();//Keyword virtual not needed, but put
                         //here for clarity. (It is also good style!)

string breed;
};

int main()
{
    Dog vdog;
    Pet vpet;

    vdog.name = "Tiny"; 
    vdog.breed = "Great Dane";
    vpet = vdog; 

    //vpet.breed; is illegal since class Pet has no member named breed

    Dog *pdog;
    pdog = new Dog;
    pdog->name = "Tiny";
    pdog->breed = "Great Dane";

    Pet *ppet; 
    ppet = pdog; 
    ppet->print(); // These two print the same output:
    pdog->print(); // name: Tiny breed: Great Dane

    //The following, which accesses member variables directly
    //rather than via virtual functions, would produce an error:
    //cout << "name: " << ppet->name << "  breed: " 
    //     << ppet->breed << endl;
    //generates an error message: 'class Pet' has no member
    //named 'breed' .
    //See Pitfall section "Not Using Virtual Member Functions"
    //for more discussion on this.

    return 0;
}

void Dog::print()
{
    cout << "name: " << name << endl;
    cout << "breed: " << breed << endl; 
}

void Pet::print()

{
    cout << "name: " << endl;//Note no breed mentioned
}

输出:

The slicing problem:
name: Tiny
Note that it was print from Pet that was invoked.
The slicing problem defeated:
name: Tiny
breed: Great Dane
name: Tiny
breed: Great Dane

最佳答案

派生类本质上以其基类的实例“开始”,然后是派生类添加的任何其他字段。所以:

class Base {
    int a, b;
};

class Derived {
    int c, d;
};

Derived 实例在内存中看起来像这样:

[a] [b]|[c] [d]

如果您现在将它“切片”到一个 Base 实例中,则会发生这种情况:

[a] [b]|nothing

另一方面,无论类型如何,指向对象的指针始终具有相同的大小,因此指向基的指针可以指向派生对象并且不会丢失任何信息。 Derived 对象的 Base 部分的开头与 Derived 对象本身的地址完全相同。

关于c++ - 理解虚函数和指针的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34381008/

相关文章:

c++ - 为什么 std::unique_ptr::reset() 总是无异常?

c++ - 编译时基类指针偏移到派生类

c# - 替换类方法而不继承

c++ - 通过智能指针和转换对基本模板参数进行模板推导

c++ - 避免空指针并保持多态性

c++ - 为什么 %p 不显示指针的全宽?

c++ - 仅获取整数作为输入,代码未按预期工作

C++ 继承错误 : expected class name before '{' token

delphi - 如何定义其参数在后代类中不同的虚函数?

c++ - 这是动态绑定(bind)还是静态绑定(bind)?