指针和对象切片



我正在学习对象切片的艰难方式,我想知道指针是否有可能被对象切片。换句话说:

  • 指针是否可以成为对象切片的受害者,或者只要你使用指针,你是否总是安全的?

这取决于你对"切片"的定义有多宽泛。从某种意义上说,当您用基指针(或引用)指向派生对象时,任何非虚函数都会被分割。例如:

class A {
    void Print() { cout << "Class An"; }
};
class B : public A {
    void DoB() {}
    void Print() { cout << "Class Bn"; }
};
B b;
A* a = &b;
a->DoB(); // Won't compile!
a->Print(); // Prints "Class A", not "Class B"

DoB的调用不起作用,因为我们使用了指向A的指针,所以编译器不知道它可以在该指针上调用DoB。这样,您将失去B的一部分,因此您可以将其视为切片的一种形式。

最后一行是一个叫做"名字隐藏"现象的例子。因为Print没有在基类中声明为virtual,而指针的类型是A,编译器不知道它应该调用B::Print而不是A::Print

这个问题的一个重要例子是你的析构函数:
class A {
    ~A() {}
};
class B : public A {
    std::vector<int> v;
};
A* a = new B;
delete a; // What happens to B::v? Undefined behaviour!

在这里,因为析构函数没有标记为virtual,所以它在非虚拟上下文中调用基类的析构函数,这意味着不会调用B的析构函数。

是——需要一个指向base的指针,以便能够引用从base派生的任何类型的对象,并且仍然保留派生对象的正确类型(并且为了它的价值,引用也是如此)。

相关内容

  • 没有找到相关文章

最新更新