C 中的 Get 和 Set ("private") 缺点?

Get and Set ("private") in C disadvantages?

我想在 C 中创建一个结构,任何人都不能直接访问它的数据,只能像在面向对象中那样通过获取和设置。我的解决方案是这样的:

Point.h

#ifndef POINT_H
#define POINT_H

typedef struct point Point;

Point *CreatePoint(int x, int y);

int Point_GetX(Point *point);
void Point_SetX(Point *point, int x);

int Point_GetY(Point *point);
void Point_SetY(Point *point, int y);

void DeletePoint(Point **p);

#endif /* POINT_H */

Point.c

#include "Point.h"

struct point{
    int x, y;
};

Point *CreatePoint(int x, int y){
    Point *p = malloc(sizeof(Point));
    if (p == NULL) return NULL;

    p->x = x;
    p->y = y;

    return p;
}

int Point_GetX(Point *point){
    return point->x;
}
void Point_SetX(Point *point, int x){
    point->x = x;
}
int Point_GetY(Point *point){
    return point->y;
}
void Point_SetY(Point *point, int y){
    point->y = y;
}

void DeletePoint(Point **p){
    if (*p != NULL){
        free(*p);
        *p = NULL;
    }
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include "Point.h"

int main(){
    Point *p = CreatePoint(2, 6);
    if (p == NULL) return EXIT_FAILURE;
    /*
    p->x = 4;               "error: dereferencing pointer
    p->y = 9;               to incomplete type"
    */
    Point_SetX(p, 4);
    Point_SetY(p, 9);

    printf("POINT(%d,%d)", Point_GetX(p), Point_GetY(p));

    DeletePoint(&p);

    return EXIT_SUCCESS;
}

当然,我绝不会为了一个简单的观点而对所有这一切进行说明,但这就是我的想法。我想知道这样做会出现什么问题,我是否应该这样做,以及是否可以这样做,如果这不是一个聪明的方法(我应该只选择 c++ xD)。 这样做的原因是我正在做一个小项目,但稍后我可能会更改一些数据结构和算法,所以如果我这样做,我只需要更改 Point.c 在这种情况下,而不是每一个我会去的地方

point->x = new_x

例如

基本上,我是在尝试做 C++ 做的事情吗?或者可以在 C 中执行此操作吗?或者没有,有缺点吗?或者这根本不是 C 的本意?哈哈

My solution was something like [this]

这是C中信息隐藏的经典方案。唯一缺少的是 DestroyPoint,一个用于释放您使用 malloc.

分配的点结构的函数

I want to know what could go wrong by doing this, whether I should be doing this or not, and if it's OK to do this.

这是一种安全的方法,只要您接受它的缺点,如下所述。

[is there] a disadvantage?

是的,有:这种方法仅限于动态分配您隐藏其内部的数据结构。你不能这样做:

Point p; // This fails, because `Point` is a forward declaration.
int x = Point_GetX(&p);

类似地,Point 的数组是禁止的;将 Point 嵌入其他 struct 也是不可能的。

Am I trying to do what C++ does?

不是真的。您的方法类似于 Objective-C,因为 C++ 没有仅在动态存储中分配对象的限制,而 Objective-C 有。不过,此限制似乎不会给 Objective-C 程序员带来太多问题。

您描述的这种封装策略在 C 库中使用得比较频繁。完全没问题。

但是请注意,它是由 约定 封装的,而不是由语言本身强制执行的,因为对 private 成员的访问是在 C++ 中强制执行的。在 C 中,虽然 you 不提供 struct point 的完整声明,但任何客户端代码都可以这样做,使其能够访问实例的成员。

需要多少个点结构实例?

就一个还是几个?

无论如何,function:CreatePoint() 在向世界提供点数据的同时也放弃了农场。

代码需要向世界隐藏点(及其字段)的实际内容。

那么只有访问函数可以访问点。

如果点需要有多个实例,

然后 CreatePoint() returns 一些整数,可以在对访问器函数的其他调用中使用到 select 正确的点。

CreatePoint 函数会执行类似于 malloc() 的操作来为新点获取空间。

应该有销毁点的功能(在table点中标记销毁?)

printf("POINT(%d,%d)", Point_GetX(&p), Point_GetY(&p));

应该是:

printf("POINT(%d,%d)", Point_GetX(p), Point_GetY(p));