重载C++虚函数的分辨率 - 引用与指针

Ago*_*ino 0 c++ virtual-functions overloading reference overload-resolution

我对C++重载分辨率的行为感到困惑.我有两个班,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;
}
Run Code Online (Sandbox Code Playgroud)

M.M*_*M.M 6

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

通过引用传递将是:

void test_ref(A &ref)
Run Code Online (Sandbox Code Playgroud)

对象是"堆栈"还是"堆积"没有区别.

同样,您的评论错误:

// references to objects allocated on stack
A heap_ref_a = *heap_pt_a;
Run Code Online (Sandbox Code Playgroud)

这里heap_ref_a是指向的对象的副本heap_pt_a.它不是参考,它们现在是两个不同的对象.参考将是:

A &heap_ref_a = *heap_pt_a;
Run Code Online (Sandbox Code Playgroud)