Сообщение Re: Язык С и инкапсуляция от 19.05.2015 15:54
Изменено 19.05.2015 17:09 Анатолий Широков
Здравствуйте, alien3128, Вы писали:
A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?
A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.
В этой теме многие посоветовали в публичный интерфейс выставить указатель на неполный тип, а в реализации использовать полный. Но даже при сокрытии реального типа от клиента никто не запрещает исследовать память по полученному указателю и ее каким-либо образом модифицировать. В свое время MS, защищая свои структуры WINAPI, озаботилась подобным и перешла на фиктивные HANDLE, являющиеся ничем иным как ключем некой внутренней структуры, по которому реализация получает реально скрытые от глаз клиента данные. Эскиз:
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, являющиеся ничем иным как ключем некой внутренней структуры, по которому реализация получает реально скрытые от глаз клиента данные. Эскиз:
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;
}