可以将派生类对象视为与基类相同类型吗? <noobieQ/>

Posted

技术标签:

【中文标题】可以将派生类对象视为与基类相同类型吗? <noobieQ/>【英文标题】:Could a derived-class object treated as if it's the same type of a bases class? <noobieQ/> 【发布时间】:2010-05-22 09:36:04 【问题描述】:

说我明白了:

class X_

public:
    void do()  


class Y_ : public X_


我有这个功能:

void foo(X_ whatever)

  whatever.do();

我可以向 foo 函数发送一个“Y_”对象吗,这可行吗?

我刚刚意识到我可以自己测试这个:)

【问题讨论】:

【参考方案1】:

是的,但它会被切掉 - 对象的所有 Y_ 部分都会被切掉,它会变成 X_。在这种情况下,您通常需要通过引用传递,因为通常 do() 将是一个虚函数:

void foo(X_ & whatever)   // ampersand means whatever is a reference

  whatever.do();

顺便说一句,我不知道你认为那些后缀的下划线对你有什么好处,但我会说“没什么”。

【讨论】:

【参考方案2】:

发送它会起作用 - 是的,但正如 Neil 指出的那样,该对象将被切片,即将基于原始 Y_ 对象创建一个 X_ 对象。一个更大的例子:

class Base

public:
    int func()  return 1; 
    virtual virtfunc ()  return 2; 


class Derived

public:
    int func()  return 3;  // Shadows (hides) Base::func. Never do this!
    virtual int virtfunc()  return 4; 


int testfunc(Base b)  return b.func(); 
int testvirtfunc(Base b)  return b.virtfunc(); 
int testfuncbyref(Base& b)  return b.func(); 
int testvirtfuncbyref(Base& b)  return b.virtfunc(); 

void main()

    Base b;
    Derived d;

    b.func(); // returns 1
    b.virtfunc(); // returns 2
    d.func(); // returns 3
    d.virtfunc(); // returns 4.

    testfunc(d); // returns 1 because func is non-virtual.
    testvirtfunc(d); // returns 2 because a Base instance is created by the call.
    testfuncbyref(d); // returns 1 because func is non-virtual.
    testvirtfuncbyref(d); // returns 4 because the real d object is used and the function is virtual.

【讨论】:

以上是关于可以将派生类对象视为与基类相同类型吗? <noobieQ/>的主要内容,如果未能解决你的问题,请参考以下文章

比较Java方法的重载与覆盖

什么情况下是重载,什么情况下是重写,什么情况下是覆盖

C++重载隐藏和覆盖的区别

6多态性-3虚函数

类成员函数的重载覆盖和隐藏

派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good