通过引用基类作为参数的函数传递派生类

时间:2013-12-02 16:32:14

标签: c++ polymorphism

请考虑以下代码:

class A {
public:
    virtual ~A() { }

    virtual void print() const {
        std::cout << "In A" << std::endl;
    }
};

class B : public A {
public:
    B() { }
    virtual ~B() { }

    virtual void print() const {
        std::cout << "In B" << std::endl;
    }
};

void doSomething(A* a) {
    a->print();
}

void doSomething(const A a) {
    a.print();
}

int main()
{
    A* a = new B();
    doSomething(a);
    doSomething(B());
    return 0;
}

为什么输出:

In B
In A

但是当您将doSomething更改为doSomething(const A& a)时,它会输出:

In B
In B

1 个答案:

答案 0 :(得分:10)

这称为切片

按值传递A时,只复制调用方对象的A部分,即可生成本地副本。由于它既有静态和动态类型的A,也就是所选择的print的覆盖。

通过引用传递,该函数获取对动态类型B的调用者对象的引用,以便选择覆盖。

使用抽象基类可以防止这样的混乱行为 - 它们不能直接实例化,因此不能通过值传递。