当前位置: 首页 > 知识库问答 >
问题:

C中的继承:如何将“超类”属性隐藏到扩展它的类中

归翔
2023-03-14

作为一种学习体验,我试图在C语言中实现简单的类继承,以及其他OOP特性。

到目前为止,我已经能够从外部上下文中正确隐藏类的“私有”函数和属性。

让我们把Point看作一个简单的类示例。它由三个模块组成:

平民的h类

#ifndef POINT_PUBLIC_H_
#define POINT_PUBLIC_H_

typedef struct Point Point;

Point* newPoint(const int x, const int y);

int getX(const Point* self);

int getY(const Point* self);

void setX(Point* self, const int x);

void setY(Point* self, const int y);

void printPoint(const Point* self);

#endif

这基本上是Point的公共接口,它还定义了引用另一个模块中声明的结构的类型Point,隐藏其属性。

保护

#ifndef POINT_PROTECTED_H_
#define POINT_PROTECTED_H_

struct Point {

    int x;
    int y;
};

#endif

它承载着实际的结构定义,还可以包含只有通过内置类才能访问的函数的原型。

然后是实现. c,它包括public. h和protected. h,并包含公共、受保护和私有函数的实际代码。

这很好,但是如果我想定义一个扩展Point的Circle类呢?

我设想了这样的情况:

#ifndef CIRCLE_PROTECTED_H_
#define CIRCLE_PROTECTED_H_

#include "../Point/protected.h"

struct Circle {

    Point parent;
    int radius;
};

#endif

由于Point的公共函数需要指向Point的指针,并且Circle结构的第一个属性是Point(不是指向它的指针),因此给定一个Circle*c对象,可以执行类似于getX((Point*)c)的操作 。虽然这很好,但我不满意的是,我可以直接访问圆模块中的点对象(当然包括圆结构中的点对象)的属性。将结构定义移动到实现模块将使其属性完全私有,但这样我就无法直接对点对象进行IStantate以设置继承机制。有没有一种方法可以在保持被扩展类的隐私的同时使继承工作?

共有1个答案

隗和裕
2023-03-14

感谢@RobertS supports Monica Cellio,我浏览了一下你链接的帖子,它实际上给了我一个想法。

我试图实际上将结构分成两部分,一个受保护的部分是由内含类可见的,另一个私有部分是在实现. c模块之外完全不可见的。

以下是我所做的:在实施中。c I定义了一个包含所有私有属性的新结构:

struct hiddenPoint {

    int x;
    int y;
};

处于受保护状态。我定义了一个引用这个新结构的类型,并在实际的Point结构中放置了一个指向它的指针

typedef struct hiddenPoint hiddenPoint;

struct Point {

    int aCircleCanSeeThis;
    hiddenPoint* hidden;
};

由于hidden是一个不透明的指针,所以即使结构点可见,它的某些属性仍可能无法访问。这个结构当然也可以承载受保护的属性,如所示。

这就是我的圆圈结构:

struct Circle {

    Point parent;
    hiddenCircle* hidden;
};

这似乎奏效了。当然,这会让事情变得有点复杂(现在是p-

 类似资料:
  • 我在下棋。我想做一个抽象的piece类,然后可以通过pawn/knight/rook/等进行扩展。假设我的piece类是这样的: 我希望Pawn具有相同的sayName功能,但我希望它具有不同的movePiece功能,因为Pawn有自己独特的移动方式。我怎么做典当,使它扩展件,并覆盖件的移动件功能?

  • 我在挣扎。 当扩展一个类时,我可以很容易地向它添加一些新属性。 但是,当我扩展基类时,如果我想向基类的对象(简单对象的属性)添加新属性,该怎么办? 下面是一个带有一些代码的示例。 基类 派生类 现在,正如您可以从行内注释中看到的,这将激怒TypeScript。但这在JavaScript中工作。那么,实现这一目标的正确方法是什么呢?如果没有,问题是在我的代码模式本身吗?什么模式适合这个问题? 也许您

  • 问题内容: 假设我有如下代码: 我如何访问间接继承到“类C”的“类A”的“ a”。我知道我可以创建“类A”的对象,也知道可以在“类B”中创建方法以返回“ super.a”(“ A类”的“ a”变量),当然,如果它是静态的,我可以像“ Aa”一样访问它。 如果还有其他直接访问它的方法,请赐教。 (提前致谢)。 问题答案: 强制转换为A,然后访问变量:

  • > RDF/OWL中继承的含义是什么? 是否可以用OWL/RDF构造面向对象语言类型的类-子类继承? 请考虑以下示例。是否“讲师”和“学生”的所有属性都将提供给“人”类? 如果有人提供给我一个很好的例子,这将是非常有帮助的答案。提前谢谢你。

  • 本文向大家介绍php类的扩展和继承用法实例,包括了php类的扩展和继承用法实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php类的扩展和继承用法。分享给大家供大家参考。具体如下: 希望本文所述对大家的php程序设计有所帮助。

  • 问题内容: 我有及其继承的类。如何从课程中获取属性? 举例来说,让这些和对象: 我想做一些事情,例如: 并得到。我怎样才能做到这一点? 问题答案: 你不能。 实例仅继承父类的方法和属性,而不继承 实例 属性。您不应混淆两者。 是 实例的实例 属性。本实例将有他们 自己 的副本属性。 通常,您将对构造函数进行编码以采用两个参数: 另一种方法是保留对实例的引用: 从那里不再继承。像这样使用它: