ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C协方差/重写/循环问题

2019-08-26 23:16:29  阅读:205  来源: 互联网

标签:c override covariance circular-dependency


我正在编写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的超类.

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

可以做些什么呢?

编辑两个评论.

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

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

我的结论是,因为:

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

后端将:

>尽可能使用前瞻性声明;
>否则将使用包括,检查后者是否为循环;如果是,它将失败并显示错误消息.

干杯,
阿图尔

解决方法:

您可以自己干净地实现协方差,而无需依赖编译器且无需任何强制转换.这是一个带有一些循环依赖的标题:

class A
{
  public:
    A* get() { return get_A(); }
  private:
    virtual A* get_A();
};

class B : public A
{
  public:
    C* get() { return get_C(); }
  private:
    virtual A* get_A();
    virtual C* get_C();    
};

class C : public A
{
  public:
    B* get() { return get_B(); }
  private:
    virtual A* get_A();
    virtual B* get_B();    
};

根据C :: get_B,用B :: get_C和C :: get_A实现B :: get_A.所有get_ *都在cxx文件中实现.您可以因为所有三个类已经完全定义.用户总是调用get().

对不起,如果格式错误,我用手机发帖.

编辑:使用静态强制转换的解决方案并不总是适用,例如当涉及虚拟继承时(那么你将需要动态强制转换).

标签:c,override,covariance,circular-dependency
来源: https://codeday.me/bug/20190826/1734870.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有