首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >访问派生类对象的字段,C++与Java

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

Stack Overflow用户
提问于 2016-05-26 10:21:08
回答 4查看 82关注 0票数 4

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

在Java中,6按预期打印:

代码语言:javascript
运行
复制
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);
    }
}

在C++中,7是打印的:

代码语言:javascript
运行
复制
#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;
}

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-05-26 10:33:51

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

当然,只要您做的事情与在Java中做的一样。

您必须记住,尽管Java具有类似的语法,但它并不相同。在Java中,语句A a = new B();创建基类型的引用,绑定到派生类型。然后,((B)a)将引用的类型转换为派生类型。

在c++中,Base b;不是引用变量。将派生对象复制到此变量将复制派生对象的基子对象.这种语言特性被称为切片。只需使用引用具有与Java代码相似的语义:

代码语言:javascript
运行
复制
Base& b = p;

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

你的赋值运算符不返回任何东西,尽管返回类型是非无效的。不返回有未定义的行为。

票数 5
EN

Stack Overflow用户

发布于 2016-05-26 10:27:04

在C++代码中,b = p;只是切片p复制到b,实际上b仍然是Base。然后static_cast<Derived&>(b)将失败并导致UB。

您可以使用引用或指针,让b实际上指向Derived。然后把它降到Derived上就可以了。

代码语言:javascript
运行
复制
int main ( int argc, char **argv ) {

    Derived p;
    Base& b = p;
    cout << static_cast<Derived&>(b).j << endl;
    return 0;
}

活着

票数 3
EN

Stack Overflow用户

发布于 2016-05-26 11:08:18

如果您的C++代码甚至接近于您的Java代码,那么您的问题可能是有意义的。事实并非如此。即使它们是用同一种语言编写的,但两个不等价的代码部分将产生不同的结果也不足为奇。

表单的main()

代码语言:javascript
运行
复制
int main ( int argc, char **argv )
{
    Base *b = new Derived;

    std::cout << ((Derived *)p)->j << endl;
    return 0;
}

是(大约)相当于Java代码,允许这样一个事实,即Java混合了C++中称为指针和引用的这些概念。它会给你你所期望的结果。

正如将语句std::cout << ((Derived *)p)->j << endl更改为等效的(在C++中) std::cout << (*((Derived *)p)).j << endl一样,这可能是对Java代码的一种更字面的解释。

实际上,您的main()函数无论如何都会产生未定义的行为,所以所有的赌注都取消了。线

代码语言:javascript
运行
复制
Derived pcasted = static_cast<Derived&>(b);

将对b的引用转换为对Derived的引用。由于b不是Derived类型的,所以pcasted的赋值将b当作是一个Derived而不是Derived。这就产生了不明确的行为。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37458019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档