C中的继承:如何将"super class"属性隐藏到扩展它的类



作为一种学习经验,我正在尝试在 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 类型,引用在另一个模块中声明的结构,隐藏其属性。

受保护的.h

#ifndef POINT_PROTECTED_H_
#define POINT_PROTECTED_H_
struct Point {
int x;
int y;
};
#endif

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

然后是implementation.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);的操作。 虽然这工作正常,但我不满意的是我可以直接访问 Circle 模块中 Point 对象(当然包括 Circle 结构中的那个对象(的属性。 将结构定义移动到实现模块将使其属性完全私有,但是我将无法直接设置Point对象以设置继承机制。 有没有办法在保护正在扩展的类的隐私的同时使继承工作?

感谢@RobertS支持莫妮卡·切利奥,我浏览了你链接的线程一段时间,它实际上给了我一个想法。

我试图将结构体实际上分成两部分,一部分是受保护的部分,它意味着对固有类可见,另一部分在implementation.c模块之外完全不可见。

这是我所做的:在implementation.c中,我定义了一个包含所有私有属性的新结构:

struct hiddenPoint {
int x;
int y;
};

在protected.h中,我定义了一个引用这个新结构的类型,并在实际的Point结构中放置了一个指向它的指针

typedef struct hiddenPoint hiddenPoint;
struct Point {
int aCircleCanSeeThis;
hiddenPoint* hidden;
};

由于 hidden 是一个不透明的指针,因此即使结构 Point 可见,它的某些属性仍然可以使其无法访问。如图所示,此结构当然也可以托管受保护的属性。

这就是我的圆结构:

struct Circle {
Point parent;
hiddenCircle* hidden;
};

它似乎有效。当然,它使事情变得有点复杂(现在它是p->hidden->x,而不仅仅是p->x(,但它做到了我一直在寻找的。不知道这是否是一个好的解决方案,也许让我知道!另外,如果有其他方法,我仍然想听听这些:)

最新更新