实现一个小型库

时间:2017-01-08 18:04:50

标签: c

鉴于以下代码实现了一个小型库,使其成为可能。

#include <stdio.h>
#include "object.h"

int main() {
    obj_instance *oi1;
    obj_instance *oi2;
    
    object_init();
    
    oi1 = Object.New();
    oi2 = Object.New();

    Object.Set(oi1, 5);
    Object.Set(oi2, 3);
    
    printf("valor de oi1: %d\n", Object.Get(oi1));
    printf("valor de oi2: %d\n", Object.Get(oi2));

    printf("oi1 y oi2 ");
    if(!Object.Equals(oi1, oi2))
        printf("NO ");
    printf("son iguales.\n");

    Object.Set(oi2, 5);
    
    printf("valor de oi1: %d\n", Object.Get(oi1));
    printf("valor de oi2: %d\n", Object.Get(oi2));
    
    printf("oi1 y oi2 ");
    if(!Object.Equals(oi1, oi2))
        printf("NO ");
    printf("son iguales.\n");
   
    Object.Free(oi1);
    puts("oi1 liberado.");
    
    Object.Free(oi2);
    puts("oi2 liberado.");
}

限制:

类型对象obj_instance的数据只能通过Object.Function库的函数访问。使用obj_instance作为malloc的参数无法获取内存。换句话说,以下代码应该失败:

obj_instance *un_objeto = malloc(sizeof(obj_instance));

如何将数据封装在C?

2 个答案:

答案 0 :(得分:3)

(我们不知道object.h因此我们无法提供帮助)

通常,在C中,您通过约定来封装(并且您无法避免它们,甚至要求编译器强制执行它们)。头文件通常包含struct&amp;的所有定义。您想要操纵union包括他们的字段)。您可以添加不使用这些字段的约定(例如,通过调用标头中定义的某些static inline函数)。至少你会通过注释记录这些约定(坏程序员有能力破坏它们,因为编译器不会强制执行所有这些约定。)

一个典型示例是FILE类型的<stdio.h>。它通常typedef - 作为一些struct _IO_FILE(该名称不重要,并且对于实现是自由的;以_开头的名称是保留的实现),这通常会被定义为某些深度包含内部标题(例如/usr/include/bits/stdio.h ...)

有时可以使用不透明类型。例如,您将在头文件中typedef struct object_st Object;并且只在某些库中定义 struct object_st(而不是在公共标头中),并系统地使用Object*(即opaque pointer)在每个公共职能中。但是你不能定义任何运行它的static inline函数(这可能意味着性能损失)。使用不透明指针,所有函数(不能是inline)都会有Object*个参数或结果(或带有Object*字段或元素的公共聚合类型)。 您可以查看GTK的真实示例,并阅读GObject(另请参阅entire GObject documentationGObject wikipage)。

请注意,C不是面向对象的语言。但是,您可以(如GTK或Linux内核代码所示;并且两者都是free software,因此您可以浏览其源代码)具有约定(有时由宏帮助)用于某些面向对象的编码风格,这仍然是一个惯例,糟糕的程序员可能会破坏。

如果不了解您的object.h,我们无法提供更好的答案。我们不知道Object是什么,我们需要了解这一点。

如果这是一个家庭作业(我们不会为你做的)并且你被要求 object.h标题,你可以做一些扣除:

  • Object应该是一些全局变量或一些宏
  • 它是一种聚合类型(又名compound data type,即structunion),因为您在其上使用.字段提取符号。
  • Object的类型可以是union吗?可能不是。那为什么?
  • 所以Objectstruct。你能说些什么呢?也许其中一些可能是function pointers
  • 另请阅读preprocessor。仔细阅读its documentation。 等...

答案 1 :(得分:-1)

强烈隐藏信息远离用户的一种肮脏方法是,根本不暴露对象定义,只提供带有void*指针的访问器。像API一样

void * New();
void Set(void* Object, int Value);
void Free(void* Object);

这完全是不安全的类型。