Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.08.2011, 01:52   #1
Начавший
Пользователь
 
Аватар для Начавший
 
Регистрация: 29.08.2011
Сообщений: 14
Стрелка Автоматический интерфейс, жесточайшая инкапсуляция. Как реализовать?

Здравствуйте.
Создаю библиотеку для работы с DirectX,
избавляющую от раздражающих мелочей.
Идея такова:
Есть один интерфейс предок всех объектов библиотеки.
Пользователь библиотеки не видит ни один класс, ни внешние включения(нет ни одной строки #include) а только
функции для работы с void* "объектами". В теле функций используется
только предок(не считая Make...), конкретный метод находится автоматом за счёт virtual.
Жесткая инкапсуляция!
Вопрос:
Как можно ограничить количество методов в интерфейсе, чтобы был
под конкретный обьект. Проблема в том что в пользовательских
функциях нужно использовать преобразование в базовый класс.
Что-то крутится в мыслях, нащупать не могу.
Код ниже естественно упрощённый, сама идея.


Код:
// Файл _1.h то что видит пользователь

#define CAMERA   void*
#define MESH     void*
#define OBJECT   void*
#define YES      bool

MESH    MakeMesh(int par1);
CAMERA  MakeCamera(int par1);
YES	  SetX(OBJECT o, float a);
YES	  Draw(OBJECT o);
Код:
// Файл _1.cpp реализация
#include "_1.h"
#include<iostream>

struct All
{
	virtual YES SetX(float a) {return 0;}
	virtual YES Draw() {return 0;}
};

struct Camera : public All
{
	float x;
	YES SetX(float a) {return x = a;}
	YES Draw() {std::cout<< x <<"\n"; return 1;}
};

struct Mesh : public All
{
	float y;
	YES SetX(float a) {return y = a;}
	YES Draw() {std::cout<< y <<"\n"; return 1;}
};

// Клиентские функции
MESH    MakeMesh(int par1)
{
	return (void*)new Mesh;
}
CAMERA  MakeCamera(int par1)
{
	return (void*)new Camera;
}
YES	   SetX(OBJECT o, float a)
{
	return ((All*)o)->SetX(a);
}
YES	   Draw(OBJECT o)
{
	return ((All*)o)->Draw();
}
Код:
// Использование
#include "_1.h"

int main()
{
	MESH   mesh =  MakeMesh(0);
	CAMERA cam  =  MakeCamera(0);

	SetX(mesh, 1);
	SetX(cam, 2);

	Draw(mesh);
	
}
Начавший вне форума Ответить с цитированием
Старый 30.08.2011, 08:28   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Вы на С пишите? В данном примере, что вы привели, все верно. Я бы вам посоветовал вашу базовую структуру рассмотреть более внимательно и выделить раздельные части, и уже те части наследовать другими структурами. Если хотите чтобы всегда был общий родитель, создайте пустой объект к примеру и от него наследуйте.

p.s. как то странно говорить о проектировании ООП иерархии с использованием не ООП языка.
BOBAH13 вне форума Ответить с цитированием
Старый 30.08.2011, 10:49   #3
Начавший
Пользователь
 
Аватар для Начавший
 
Регистрация: 29.08.2011
Сообщений: 14
По умолчанию

BOBAH13, я использую C++. Структуры в коде только для краткости кода и удобства понимания идеи. Если базовый разделить на части, то какая часть будет в деле при вызове ((All*)o)->??. Если наследовать от пустого класса, то нельзя вызвать ни один метод, базового - их нет.
Жаль невозможно сделать такое:
Код:
struct All
{
	virtual A* operator->(){return this;}
	virtual B* operator->(){return this;}
};

struct A : public All{/*определение*/};
struct B : public All{/*определение*/};
перегрузить селектор -> нельзя
Начавший вне форума Ответить с цитированием
Старый 30.08.2011, 10:58   #4
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от Начавший Посмотреть сообщение
BOBAH13, я использую C++. Структуры в коде только для краткости кода и удобства понимания идеи. Если базовый разделить на части, то какая часть будет в деле при вызове ((All*)o)->??. Если наследовать от пустого класса, то нельзя вызвать ни один метод, базового - их нет.
Жаль невозможно сделать такое:
Код:
struct All
{
	virtual A* operator->(){return this;}
	virtual B* operator->(){return this;}
};

struct A : public All{/*определение*/};
struct B : public All{/*определение*/};
перегрузить селектор -> нельзя
Или я давно не писал на С++ или совсем не понимаю назначение, вернее обратную совместимость с С, struct. Почему вы не используете ООП, а именно class? На счет вашей проблемы, чтобы ее решить нам, мне по крайней мере, требуется вникнуть в сущности, которые вы хотите описать. Тут дело не в коде вовсе, с моей точки зрения. Я считаю вам следует рассмотреть на бумаге, какие сущности и что они должны и что над ними должно производиться, какие именно действия и что именно эти сущности должны представлять. Опишите все что у вас есть, обычно после этого вы увидите раздельные части и поймете как все описать (для меня работает). А то, что вы тут код мизерный даете, по нему никак, к сожалению, не могу помочь.
BOBAH13 вне форума Ответить с цитированием
Старый 30.08.2011, 14:55   #5
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Цитата:
Почему вы не используете ООП, а именно class?
ВОВАН13, А чем по вашему struct отличается от class, кроме названия и дефолтных спецификаторов доступа к членам и при наследовании?
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 30.08.2011, 15:13   #6
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от Syuf Посмотреть сообщение
ВОВАН13, А чем по вашему struct отличается от class, кроме названия и дефолтных спецификаторов доступа к членам и при наследовании?
У меня просто "плохая" привычка следовать документации и основных принципов используемого языка.
BOBAH13 вне форума Ответить с цитированием
Старый 30.08.2011, 15:28   #7
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Цитата:
У меня просто "плохая" привычка следовать документации и основных принципов используемого языка.
Ниче не понял.
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 30.08.2011, 17:21   #8
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Цитата:
Сообщение от BOBAH13 Посмотреть сообщение
У меня просто "плохая" привычка следовать документации и основных принципов используемого языка.
По стандарту ключевое слово struct отличается от class только используемым спецификатором доступа по-умолчанию. Причем тут ваше высказывания относительно ООП - непонятно.
Кстати, код из первого поста не мог быть написан на С, в С нет наследования
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 30.08.2011, 19:03   #9
Начавший
Пользователь
 
Аватар для Начавший
 
Регистрация: 29.08.2011
Сообщений: 14
По умолчанию

Люди, зачам гадать над очевидным...
Неверно я свою задачу описал(не точно).
Хочу чтобы по селектору(в смысле "->") базового класса(структкры) выезжал интерфейс(поля) истинного класса(структкры) потомка.
Причём базовый не содержит тех методов что в производных классах.
Я почти решил задачу.
Начавший вне форума Ответить с цитированием
Старый 31.08.2011, 00:41   #10
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Начавший

Жесткая инкапсуляция!

на самом деле это жОсткое порно.

никакого контроля типов.
особо доставляет абсолютная беспомощность "библиотеки" к такого рода (говно)коду:

CAMERA c = MakeMesh(0);
MESH m = MakeCamera(0);

а самая веселуха начинается здесь.

int i = 0;
Draw(&i);

Если базовый разделить на части, то какая часть будет в деле при вызове ((All*)o)->??. Если наследовать от пустого класса, то нельзя вызвать ни один метод, базового - их нет.

Схема дальнейших действий мне видится примерно такой: сначала читать про dynamic_cast. Потом - выкинуть dynamic_cast и читать Буча - про полиморфизм и ООП. Потом всё переделать.
Rififi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как реализовать подобный графический интерфейс alexplato Общие вопросы .NET 7 14.09.2011 07:59
Инкапсуляция Syltan Общие вопросы C/C++ 21 08.10.2009 17:03
Инкапсуляция psycho-coder Общие вопросы Delphi 4 14.08.2009 13:04
Инкапсуляция Lyxor Общие вопросы Delphi 0 29.06.2008 13:06