首页  >  文章  >  后端开发  >  在 C 中使用继承层次结构向量时如何避免对象切片?

在 C 中使用继承层次结构向量时如何避免对象切片?

DDD
DDD原创
2024-11-01 09:00:03860浏览

How Can Object Slicing Be Avoided When Working with Vectors of Inheritance Hierarchies in C  ?

C 中的向量和多态性:对象切片揭秘

在处理 C 中的继承层次结构向量时,可能会遇到一些微妙的复杂情况妨碍预期的行为。考虑以下示例:

<code class="cpp">class Instruction
{
public:
    virtual void execute() {  }
};

class Add: public Instruction
{
private:
    int a;
    int b;
    int c;
public:
    Add(int x, int y, int z) {a=x;b=y;c=z;}
    void execute() { a = b + c;  }
};</code>

现在,想象将 Add 对象存储在基类指针的向量中:

<code class="cpp">void some_method()
{
    vector<Instruction*> v;
    Instruction* i = new Add(1,2,3)
    v.push_back(i);
}</code>

稍后,在一个单独的方法中,我们尝试调用对向量的最后一个元素执行函数:

<code class="cpp">void some_other_method()
{
    Instruction ins = v.back();
    ins.execute();
}</code>

一个常见的误解是,execute 函数的行为就像在 Add 对象上调用一样。然而,事实并非如此。

问题源于向量存储值的方式:它们存储对象的副本,而不是引用。因此,当将 Add 对象推入向量时,它会被复制,从而产生指令类型的对象,从而丢失特定于 Add 的数据和方法。这称为对象切片。

为了避免对象切片,我们需要修改向量以保存引用而不是副本:

<code class="cpp">vector<Instruction*> ins</code>

或者,我们可以使用 std::reference_wrapper:

<code class="cpp">vector< std::reference_wrapper<Instruction> > ins</code>

通过使用引用,我们在向量中保留对象的原始类型,从而允许预期的多态行为。

以上是在 C 中使用继承层次结构向量时如何避免对象切片?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn