【问题标题】:Overloading resolution of C++ virtual functions - references vs pointersC++ 虚函数的重载解析 - 引用 vs 指针
【发布时间】:2014-08-26 12:35:00
【问题描述】:

我对 C++ 重载决议中的 A 行为感到困惑。我有2个班级,A和B,A

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

对此有何解释?

#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;
}

【问题讨论】:

    标签: c++ reference overloading virtual-functions overload-resolution


    【解决方案1】:

    函数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;
    

    【讨论】:

    • 那么,test_ref 只是复制 B-as-A,而忽略了 B-as-B 部分?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2013-06-25
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多