在理解切片之后,据我所知,它可以使用指向动态变量的指针来破解。但是怎么了?为什么那时没有切片?我想自己,但我不确定。在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
答案 0 :(得分:3)
派生类本质上是“开始”其基类的实例,后跟派生类添加的任何其他字段。所以:
class Base {
int a, b;
};
class Derived {
int c, d;
};
Derived
实例在内存中看起来像这样:
[a] [b]|[c] [d]
如果您现在将其“切片”到Base
实例中,则会发生这种情况:
[a] [b]|nothing
另一方面,指向对象的指针总是大小相同,无论类型如何,因此指向基类的指针可以指向派生对象而不会丢失任何信息。 Base
对象的Derived
部分的开头与Derived
对象本身的地址完全相同。
答案 1 :(得分:0)
定义类时,其成员定义其内存布局。类数据成员按顺序存储在存储器中。
当您派生类并使用继承时,派生类的数据成员只需添加到基类的数据成员之后。
因此,当切片发生时,你就会有效地&#34;看到&#34;只有基类成员。
现在,关于&#34;为什么指针oto基类没有切片派生类的对象&#34; ?
继承最重要的一个方面不是它为派生类提供成员函数,而是它提供了在派生类和基类之间表达的关系。派生类可以被视为&#34;基类的一种类型&#34; 。
如需进一步阅读,请查看向上转播和向下转换这两个词。
向上转换正在将派生类引用或指针转换为基类。换句话说,向上转换允许我们将派生类型视为它的基类型。
要从评论部分回答您的问题,&#34;什么是覆盖?
从a派生与虚拟函数具有相同名称和类型的函数 基类,称为重写。