【发布时间】: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 结构,这可能知道定义.但我永远不会在生产代码中这样做;) -
我不认为从
Circle中隐藏Point是一个好主意(在C 中)。您有一个图形源集,然后是用户代码。图形代码应该知道所有形状和操作的实现;用户代码可以使用 void 指针。
标签: c oop inheritance struct visibility