Информация об изменениях

Сообщение Re: Язык С и инкапсуляция от 19.05.2015 15:54

Изменено 19.05.2015 17:09 Анатолий Широков

Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

В этой теме многие посоветовали в публичный интерфейс выставить указатель на неполный тип, а в реализации использовать полный. Но даже при сокрытии реального типа от клиента никто не запрещает исследовать память по полученному указателю и ее каким-либо образом модифицировать. В свое время MS, защищая свои структуры WINAPI, озаботилась подобным и перешла на фиктивные HANDLE, являющиеся ничем иным как ключем некой внутренней структуры, по которому реализация получает реально скрытые от глаз клиента данные. Эскиз:

// interface.h

typedef int HANDLE;

HANDLE open();
void use(HANDLE);
void close(HANDLE);

// interface.c
#include "interface.h"

const int N=16;

struct data {
   int opened;
   char filename[128];
} buffer[N] = {0};
int h = N-1;

HANDLE open() 
{
   h = (h + 1)%N;
   assert(buffer[h].opened == 0);
   buffer[h].opened = 1;
   return h;
}

void use(HANDLE h) 
{
   struct data* p = &buffer[h];
   ...
}

void close(HANDLE h)
{
   buffer[h].opened = 0;
}
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

В этой теме многие посоветовали в публичный интерфейс выставить указатель на неполный тип, а в реализации использовать полный. Но даже при сокрытии реального типа от клиента никто не запрещает исследовать память по полученному указателю и ее каким-либо образом модифицировать. В свое время MS, защищая свои структуры WINAPI, озаботилась подобным и перешла на фиктивные HANDLE, являющиеся ничем иным как ключем некой внутренней структуры, по которому реализация получает реально скрытые от глаз клиента данные. Эскиз:

// interface.h

typedef int HANDLE;

HANDLE open();
void use(HANDLE);
void close(HANDLE);

// interface.c
#include "interface.h"

const int N=16;

struct data {
   int opened;
   char filename[128];
} buffer[N] = {0};
int h = 0;

HANDLE open() 
{
   // find free handle
...
   return h;
}

void use(HANDLE h) 
{
   struct data* p = &buffer[h];
   ...
}

void close(HANDLE h)
{
   buffer[h].opened = 0;
}