C中的继承:如何将“超类”属性隐藏到扩展它的类
Posted
技术标签:
【中文标题】C中的继承:如何将“超类”属性隐藏到扩展它的类【英文标题】:Inheritance in C: how to hide "super class" attributes to the class extending it 【发布时间】:2020-05-28 09:00:24 【问题描述】:作为一种学习体验,我尝试在 C 中实现简单的类继承,以及其他 OOP 特性。
到目前为止,我已经能够从外部上下文中正确地隐藏类的“私有”函数和属性。
让我们将 Point 视为一个简单的类示例。它由三个模块组成:
public.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
对象,就可以执行类似 @ 的操作987654326@。
虽然这很好用,但我不满意的是我可以直接访问 Circle 模块中的 Point 对象(当然包括 Circle 结构中的那个)的属性。
将结构定义移动到实现模块将使其属性完全私有,但我将无法直接实例化 Point 对象以设置继承机制。
有没有办法让继承工作,同时维护正在扩展的类的隐私?
【问题讨论】:
在 C 中编程时可以使用 OOP 概念,但这是您达到极限的地方。对于这些细节,您应该使用真正的 OO 语言。 我知道。我不一定要这样做,因为我打算在实际程序中使用这些概念。正如我所说,这只是一个学习新东西的实验。当然,如果我的要求真的无法完成,我可以接受。但是,如果有人知道一种不同的、更有效的方法,我很想了解它:) 您可能会使用(足够大的)字符缓冲区实例化Point
的不透明版本,传递它并将其转换为函数/源文件中的真实 Point 结构,这可能知道定义.但我永远不会在生产代码中这样做;)
相关:***.com/questions/351733/…
我不认为从Circle
中隐藏Point
是一个好主意(在C 中)。您有一个图形源集,然后是用户代码。图形代码应该知道所有形状和操作的实现;用户代码可以使用 void 指针。
【参考方案1】:
感谢@RobertS 对 Monica Cellio 的支持,我浏览了您链接的主题一会儿,它实际上给了我一个想法。
我试图将结构实际拆分为两部分,一个是受保护的部分,它意味着对继承类可见,另一个是在 implementation.c 模块之外完全不可见的私有部分。
这是我所做的:在 implementation.c 中我定义了一个包含所有私有属性的新结构:
struct hiddenPoint
int x;
int y;
;
在 protected.h 中,我定义了一个引用这个新结构的类型,并在实际的 Point 结构中放置了一个指向它的指针
typedef struct hiddenPoint hiddenPoint;
struct Point
int aCircleCanSeeThis;
hiddenPoint* hidden;
;
由于 hidden 是一个不透明的指针,即使 struct Point 是可见的,它的一些属性仍然可以被设置为不可访问。这个结构当然也可以托管受保护的属性,如图所示。
这就是我的 Circle 结构:
struct Circle
Point parent;
hiddenCircle* hidden;
;
它似乎工作。当然,它使事情变得有点复杂(现在它是 p->hidden->x,而不仅仅是 p->x),但它可以满足我的要求。不知道有没有好的解决方法,请告诉我!另外,如果还有其他方法,我仍然想听听这些方法:)
【讨论】:
以上是关于C中的继承:如何将“超类”属性隐藏到扩展它的类的主要内容,如果未能解决你的问题,请参考以下文章