传递给接受基类的函数的变量是否仍保留其派生类最多?

时间:2013-05-16 23:06:16

标签: c++ class function inheritance

例如,考虑:

class Deriv : public Base {...};
...
bar(Deriv d);
bar(Base b);
foo(Base b) {bar(b);}
...
Deriv x;
foo(x); // does x get treated as Base for the bar() call
        // or retain its Deriv type?

如果foo通过引用传递了该怎么办?

2 个答案:

答案 0 :(得分:6)

您正在按值传递,因此您正在创建一个Base类型的新对象,并为其分配一个副本。

非常糟糕,你会经历切片......它不会保留它的阶段而不建议。 http://en.wikipedia.org/wiki/Object_slicing

通过引用或const引用传递,无论如何更好更快:

bar(const Base& b)

或传递指向该对象的指针,您将保留该状态。     bar(Base * b);

这将是处理此问题的正确方法。

答案 1 :(得分:3)

在您的示例中,x将是Base,这是因为您在调用函数时正在创建新的Base对象。也就是说,在函数调用中,调用Base的构造函数,创建从参数(Baseb子对象复制的x Base (称为对象切片)。它没有被视为作为Base,它会创建一个新的Base

但是,如果您将参数视为Base &,则会将其视为Derived,请考虑以下代码:

#include <iostream>
class Base {
    public:
        virtual void func() const {
            std::cout << "Base::Func()" << std::endl;
        }

};

class Derived : public Base {
    public:
        virtual void func() const {
            std::cout << "Derived::Func()" << std::endl;
        }
};

int do_func_value(Base b){
    b.func(); // will call Base::func
}

int do_func_ref(const Base & b){
    b.func(); // will call whatever b's actual type is ::func
}

int main(void){
    Derived d;
    do_func_value(d);
    do_func_ref(d);
    return 0;
}

此输出:

Base::Func()
Derived::Func()