C语言隐藏结构体的实现方法

前言:

前些天在搞win32,被windows花里胡哨的结构弄得生不如死,脑子里莫名其妙蹦出了一个想法:能不能定义一些结构体,外部可以用它来定义变量,然而却不能改变它的成员的值, 就像C++,Java一类语言的class一样对数据进行保护。好吧,其实是我还没吃饱撑着随便乱搞
参照了网上很多的说法,自己胡乱地搞了几个小时给弄出来了。

正文:

直接上代码:

book.cpp

#include "book.h"
struct book{
    int price;
    char *name;
};

PBOOK CreateBook(int price, char *name)
{
    PBOOK Book1 = (PBOOK)malloc(sizeof(BOOK));
    Book1->price = 100;
    Book1->name = 0;
    return Book1;
}

void FreeBook(PBOOK book)
{
    free(book);
} 

上述源代码文件定义了一个结构和两个函数,同时包含一个自身的头文件

book.h

#include <malloc.h>
#define PBOOK BOOK *

struct book;
typedef struct book BOOK;

PBOOK CreateBook(int price, char *name);
void FreeBook(PBOOK book);

头文件中声明了两个函数和结构体,其中用typedef给结构体定义为一种类型。因为源代码文件会包含这个头文件,所以在源代码中也可以使用头文件中的宏

main.cpp

#include <stdio.h>
#include "book.h"
int main()
{
    PBOOK a = CreateBook(20, "1231321231");    // 定义的变量必须是指针类型 
    printf("%d",a);
} 

注意定义的BOOK类型 必须是指针(BOOK *类型,参照头文件的宏定义) 一旦定义为

BOOK a;

就会报错,因为我们包含的头文件只有BOOK的声明,定义为BOOK a的话编译器不知道要给a分配多少内存空间,会引发以下类似类型错误:

[Error] variable 'BOOK a' has initializer but incomplete type

编译通过之后,可以用printf函数打印分配的地址,看下是否分配成功!
这样定义的变量的所有对成员的操作都要写到源代码文件中(包括基本的输入输出函数都要),因为在主函数中,这些变量的成员的值无法被直接更改!
如:

main.cpp

#include <stdio.h>
#include "book.h"
int main()
{
    PBOOK a = CreateBook(20, "1231321231");    // 定义的变量必须是指针类型 
    printf("%d %d",a, a->price);
} 

编译器会报类型错误,

[Error] invalid use of incomplete type 'BOOK {aka struct book}'