访问派生类对象的字段,C++与Java

rok*_*rok 4 c++ java inheritance

如果在将此对象赋值给java中的基类类型的变量之后访问派生类对象的字段,则得到预期的行为,即打印字段的派生类的值.在字段的c ++值中,打印属于基类.

在Java中,按预期打印6:

class Ideone
{

    static class A {
        static int a = 7;
    }
    static class B extends A {
        static int b = 6;
    }
    public static void main (String[] args) throws java.lang.Exception
    {

        A a = new B();
        System.out.println(((B)a).b);
    }
}
Run Code Online (Sandbox Code Playgroud)

在C++中,打印出7个:

#include <iostream>
using namespace std;

class Base {
    int i = 7;
public:

    Base(){
        std::cout << "Constructor base" << std::endl;
    }
    ~Base(){
        std::cout << "Destructor base" << std::endl;
    }
    Base& operator=(const Base& a){
        std::cout << "Assignment base" << std::endl;
    }
};

class Derived : public Base{
public:
    int j = 6;
};

int main ( int argc, char **argv ) {
    Base b;
    Derived p;
    cout << p.j << endl;
    b = p;
    Derived pcasted = static_cast<Derived&>(b);
    cout << pcasted.j << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否有可能在c ++中实现类似的行为(打印6).

eer*_*ika 5

是否有可能在c ++中实现类似的行为(打印6).

当然,只要你做与Java相同的事情.

您必须记住,即使Java具有相似的语法,它也不完全相同.在Java中,该语句A a = new B();创建一个基类型的引用,绑定到派生类型.((B)a)然后将引用的类型转换为派生类型.

在c ++中,Base b;不是引用变量.将派生对象复制分配给此变量将复制派生对象的基础子对象.此语言功能称为切片.只需使用引用就可以获得与Java代码类似的语义:

Base& b = p;
Run Code Online (Sandbox Code Playgroud)

如果Base通过Derived&引用访问具体类型的对象,则会调用未定义的行为.

PS尽管返回类型是非空的,但您的赋值运算符不会返回任何内容.不返回有未定义的行为.