C++虚拟函数的重载解析-引用与指针

Overloading resolution of C++ virtual functions - references vs pointers

本文关键字:引用 指针 虚拟 函数 重载 C++      更新时间:2023-10-16

我对C++重载解析中的A行为感到困惑。我有两个班,A和B,其中A<:B.A有一个虚拟函数f,而B应该覆盖该函数。

然而,当我使用引用调用虚拟函数时,它们似乎并不像虚拟函数那样工作。起初,我认为这是由于对象是在堆栈上而不是堆上分配的,但现在我发现,即使我使用对堆上分配对象的引用,这种奇怪的行为也会发生。

对此有什么解释?

#include<iostream>
using namespace std;
class A{
public:
    virtual void foo(){ cout << "A::foo" << endl; }
};
class B : public A{
public:
    virtual void foo(){ cout << "B::foo" << endl; }
};
void test_pt(A* pt){
    cout << "test_pt " << (int)pt << " ";
    pt->foo();
}
void test_ref(A ref){
    cout << "test_ref " << (int)&ref << " ";
    ref.foo();
}
int main(int argc, char* argv[]){
    // pointers to objects allocated on heap
    A* heap_pt_a = new A;
    B* heap_pt_b = new B;
    // virtual functions work as intended
    test_pt(heap_pt_a); // test_pt 4975912 A::foo
    test_pt(heap_pt_b); // test_pt 4975960 B::foo
    // references to objects allocated on heap
    A heap_ref_a = *heap_pt_a;
    B heap_ref_b = *heap_pt_b;
    // virtual functions work as non-virtual
    test_ref(stack_ref_a); // test_ref 1571400 A::foo
    test_ref(stack_ref_b); // test_ref 1571400 A::foo
    // references to objects allocated on stack
    A stack_ref_a;
    B stack_ref_b;
    // virtual functions work as non-virtual
    test_ref(stack_ref_a); // test_ref 1571400 A::foo
    test_ref(stack_ref_b); // test_ref 1571400 A::foo
    // references to stack used as pointers to stack
    // virtual functions work as intended
    test_pt(&stack_ref_a); // test_pt 1571724 A::foo
    test_pt(&stack_ref_b); // test_pt 1571712 B::foo
    return 0;
}

函数test_ref按值取一个A。这不是通过引用传递的。该函数中的参数ref是从调用函数中的对象复制的本地对象。(如果它是从B复制的,则称为切片)。

通过参考将是:

void test_ref(A &ref)

对象是"堆栈"还是"堆"没有区别。

同样,你的评论在中也是错误的

// references to objects allocated on stack
A heap_ref_a = *heap_pt_a;

这里,heap_ref_aheap_pt_a所指向的对象的副本。它不是一个参考,它们现在是两个不同的对象。一个参考是:

A &heap_ref_a = *heap_pt_a;