gpt4 book ai didi

c++ - C++ 协方差/覆盖/循环问题

转载 作者:太空狗 更新时间:2023-10-29 20:30:34 25 4
gpt4 key购买 nike

我正在编写 Java 子集编译器的后端。后台写C++代码。不过,有一些假设的 Java 代码,我不知道如何将其转换为 C++。

以下代码显示了一个示例问题。 A由B扩展,B由C扩展,这里分别是三个头文件A.h、B.h和C.h:


#ifndef A_H
#define A_H

class B;

class A {
public: virtual B* get();
}

#endif /* !defined(A_H) */
==========================
#ifndef B_H
#define B_H

#include "A.h"

class C;

class B : public A {
public: virtual C* get();
}

#endif /* !defined(B_H) */
==========================
#ifndef C_H
#define C_H

#include "B.h"

class C : public B {
}

#endif /* !defined(C_H) */

可以看出,B重写了A的方法get()。覆盖方法返回指向相应子类的指针,我猜这在 C++ 中是有效的,这要归功于协变性。

我不知道的是通知编译器的方式,C 确实是 B 的子类,因此覆盖方法是有效的。

B.h 中 C 的前向声明,就像在代码中看到的那样,是不够的,因为它没有说明 C 的父类(super class)。

将 C.h 包含在 B.h 中将是循环的,因为 C.h 已经包含 B.h。后者是必需的,因为仅具有父类(super class)的前向声明是不够的。

可以用它做什么?

编辑两条评论。

1 其中一位发帖人声称,以下内容在 Java 中是不可能的,因此我添加了一个 Java 版本:

A.java:


class A {
public B get() {
return null;
}
}

B.java:


class B extends A {
public C get() {
return null;
}
}

C.java:


class C extends B {
}

它编译得很好。

2 这种有点奇怪的案例,我并不坚持要整理。如果它们不能在 C++ 中转换为可读代码,那么很好,后端将失败并显示一条错误消息。事实上,我更感兴趣的是像 C++ 中那样解决循环依赖的通用方法。

编辑 2

谢谢大家,我对这个网站的效率印象深刻。

我的结论是,因为:

  1. 生成的头文件将被其他程序员使用;
  2. 根据您的回答猜测,可能没有解决方案可以生成简单、可读的头文件;
  3. 涉及返回类型的循环引用可能很少见;
  4. 我避免使用 C++,因为除其他外,它允许这样的解决方案 --我知道 C++ 有其用途,但就我个人而言,我更喜欢语法更简单的语言,例如 Java;

后端将:

  1. 尽可能使用前向声明;
  2. 否则它将使用include,检查后者是否是循环的;如果是,它将失败并显示一条错误消息。

干杯,阿图尔

最佳答案

当您通过机器生成代码时,可以使用一些肮脏、肮脏的技巧。

class B;

class A {
public: virtual B* CLASS_A_get();
}

class C;

class B : public A {
public:
virtual B* CLASS_A_get();
virtual C* CLASS_B_get();
}

class C : public B {
}

// In B's .cpp file, you can include C.h
#include "C.h"
B* B::CLASS_A_get() {
return CLASS_B_get();
}

关于c++ - C++ 协方差/覆盖/循环问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6599246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com