向下投射会导致基础构件无法正确修改C++

Downcasting causes base member to not be modified correctly C++

本文关键字:构件 C++ 修改      更新时间:2023-10-16

我有一个基类和一个派生类。基类内部是一个值,以及一个从成员中减去该值的函数虚拟modify(int val)。此外,派生类重写modify(int val),后者在调用基类的方法之前进行一些检查。

当在main()中使用derivedObject.modify(someVal)调用时,一切正常。然而,当我调用调用该modify()的函数modifyAndPrintValue(Base obj)时,调用模式正确地命中Derived::modify() => Base::modify(),但下次打印时,基类中存储的值不会被修改(它是原始值)。

class Base
{
   public:
            int value;
            void virtual modify(val) {value -= val;}
            int getValue() {return value;}
}
class Derived: public Base
{
    public:
            void modify(val) {Base::modify(val);}
}
void modifyAndPrint(Base obj)
{
     obj.modify(5);
     cout << obj.getValue(); // should print 9 -5 = 4
}
int main()
{
    Derived derivedObj(); //assume this initializes the object with a value, say 10
    derivedObj.modify(1);
    cout << derivedObj.getValue(); // returns correct value, 9 (10 - 1)
    modifyAndPrint(derivedObj); // does not print correct value, still prints 9
}

我做错了什么?

C++是基于值的:当您不通过指针或引用传递对象时,它们会被复制。副本将具有由tbe函数解密的静态类型,即任何派生部分都将被"切片"掉。你想通过引用传递你的对象:

modifyAndPrint(Base& obj) {
    ...
}

您将Base obj传递给modifyAndPrint,这意味着您将按值传递它,这意味着生成它的副本并将其提供给函数。如果希望函数修改原始值,则必须通过引用传递,即Base &obj。有关进一步的阅读,请参阅C++中的传递引用/值。