什么时候引用铸造切片对象?

When does reference casting slice objects?

看看这段代码:

#include <iostream>


class A{
public:
    int x;
    
    virtual void f(){std::cout << "A f\n";}
    
};

class B: public A
{
public:
    int y;
    
    void f() {std::cout << "B f\n";}
};



void fun( A & arg)
{
    std::cout << "fun A called" << std::endl;
    arg.f(); 
    // arg.y = 222; - this gives error, compiler's work?
    arg.x = 2223333;
}
void fun(B & arg){
    std::cout << "fun B called" << std::endl;
    arg.f();

}

int main()
{
    B b;
    b.y = 12;
    b.x = 32;

    fun(static_cast<A&>(b));
    
    std::cout << b.x << " " << b.y << std::endl;
    
    return 0;
}

当我将 b 引用为 A& 时究竟发生了什么?我猜对类型 A 'arg' 的引用是在函数 'fun()' 中创建的,现在它只是编译器的工作来区分类型?这意味着没有创建实际对象并且没有发生切片并且它在内存中仍然是同一个对象,但是编译器会将它视为类型 A? (意味着在函数调用后我可以安全地将 b 用作类型 B?)

我假设这是真的,因为实例的 vptr 没有改变(类型 A 的 arg 称为 B 的虚函数覆盖),但我不完全确定在引用转换期间幕后发生了什么。

此外,如果我将 static_cast<A&>(b) 分配给一个类型 A 的新对象,我假设那是一个类型 A 的新对象的构造和切片发生的时候?

是的,你似乎明白了。 :-)

A B 也是一个 A(通过继承),因此它可以绑定到 A&B&。没有其他事情发生,它只是对现有对象的引用。

如果您将 B 对象分配给 A 对象,则会发生切片,例如 A a = b;,它只会复制 [=18] 的继承 A 部分=].