使用C语言进行数据封装的OOP编程 [英] OOP programming with data encapsulation in C

查看:116
本文介绍了使用C语言进行数据封装的OOP编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试根据此处的这篇文章

I tried to do data encapsulation in C based on this post here https://alastairs-place.net/blog/2013/06/03/encapsulation-in-c/.

在头文件中,我有:

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

// Pre-declaration of struct. Contains data that is hidden
typedef struct person *Person;


void getName(Person obj);
void getBirthYear(Person obj);
void getAge(Person obj);
void printFields(const Person obj);

#endif

在"functions.c"中,我已经定义了这样的结构

In ´functions.c´ I have defined the structure like that

#include "Functions.h"

enum { SIZE = 60 };

struct person
{
    char name[SIZE];
    int birthYear;
    int age;
};

我也定义了功能.

在main.c中,我有:

In main.c I have:

#include "Functions.h"
#include <stdlib.h>

int main(void)
{
    // Works because *Person makes new a pointer
    Person new = malloc(sizeof new);

    getName(new);
    getAge(new);
    getBirthYear(new);
    printFields(new);

    free(new);

    return 0;
}

是真的,当我使用Person new时,由于typedef struct person *Person;new已经是指针.

Is it true, that when I use Person new, new is already pointer because of typedef struct person *Person;.

链接器怎么可能看不到我在struct person

How is it possible, that linker cannot see the body and members that I have declared in my struct person

这只能使用指针吗?

在我的情况下,是实现OOP原理以在functions.h中创建不同的struct的正确方法(也是唯一方法),如下所示:

Is the correct (and only) way to implement OOP prinicples in my case to make a different struct in functions.h like so:

typedef struct classPerson
{   // This data should be hidden
    Person data;

    void (*fPtrGetName)(Person obj);
    void (*fPtrBirthYear)(Person obj);
    void (*fPtrGetAge)(Person obj);
    void (*fPtrPrintFields)(const Person obj);
} ClassPerson;

推荐答案

首先,通常最好不要将指针隐藏在typedef后面,而应让调用者使用指针类型.这样可以防止在阅读和维护代码时发生各种误解.例如,如果您没有意识到Person是指针类型,则void printFields(const Person obj);看起来像胡话.

First of all, it is usually better to not hide pointers behind a typedef, but to let the caller use pointer types. This prevents all kinds of misunderstandings when reading and maintaining the code. For example void printFields(const Person obj); looks like nonsense if you don't realize that Person is a pointer type.

我是否正确理解,当我使用Person new时,由于typedef struct person * Person;而new已经是指针了.

Have I understood correctly, that when I use Person new, new is already pointer because of typedef struct person *Person;.

是的.您由于提到的typedef而感到困惑.

Yes. You are confused because of the mentioned typedef.

链接器怎么可能看不到我在结构人"中声明的主体和成员?

How is it possible, that linker cannot see the body and members that I have declared in my ´struct person´?

链接器可以看到所有链接的内容,否则您将无法获得有效的可执行文件.

The linker can see everything that is linked, or you wouldn't end up with a working executable.

编译器可在翻译单元"上使用(大致表示.c文件及其所有包含的标头).编译调用方的翻译单元时,编译器看不到functions.c,而只看到functions.h.并且在functions.h中,struct声明给出了不完整类型.意思是此结构定义在其他地方".

The compiler however, works on "translation units" (roughly means a .c file and all its included headers). When compiling the caller's translation unit, the compiler doesn't see functions.c, it only sees functions.h. And in functions.h, the struct declaration gives an incomplete type. Meaning "this struct definition is elsewhere".

这只能使用指针吗?

Is this only possible using pointer?

是的,这是您要在C语言中进行适当的OO编程的唯一方法.此概念有时称为不透明指针不透明类型.

Yes, it is the only way if you want to do proper OO programming in C. This concept is sometimes called opaque pointers or opaque type.

(尽管您也可以通过static关键字实现穷人的私人封装".通常不建议这样做,因为它不是线程安全的.)

(Though you could also achieve "poor man's private encapsulation" though the static keyword. Which is usually not really recommended, since it wouldn't be thread-safe.)

在我的情况下,这是实现OOP原理以在function.h中创建不同结构的正确(也是唯一的)方法:

Is the correct (and only) way to implement OOP prinicples in my case to make a different struct in functions.h like so:

是的,是的(除了关于提到的指针typedef的nit-pick之外).尽管这是实现多态的方式,但是不必使用指向公共函数的函数指针.

Pretty much, yeah (apart from the nit-pick about the mentioned pointer typedef). Using function pointers to the public functions isn't necessary though, although that's how you implement polymorphism.

您的示例缺少的是构造函数"和析构函数".没有它们,代码将毫无意义. malloc和free调用应该在其中,而不是由调用者完成.

What your example lacks though is a "constructor" and "destructor". Without them the code wouldn't be meaningful. The malloc and free calls should be inside those, and not done by the caller.

这篇关于使用C语言进行数据封装的OOP编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆