Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как обойтись без void*

284
03 апреля 2006 года
michael_is_98
587 / / 25.02.2005
Здравствуйте!

Вопрос следующего плана: мне нужно использовать структуру
наподобие
struct
{
int i;
void *data;
};

Т.е. в зависимости от значения члена i член data может указывать на данные других типов (структур, классов, целых, вещест. переменных).

Знаю, что подобные структуры могут приводить к различным ошибкам при конструировании приложения и его работе. Как можно обойтись без подобных струтур (как их развести)?
324
03 апреля 2006 года
AndreySar
532 / / 01.08.2004
Цитата:
Originally posted by michael_is_98
Здравствуйте!

Вопрос следующего плана: мне нужно использовать структуру
наподобие
struct
{
int i;
void *data;
};

Т.е. в зависимости от значения члена i член data может указывать на данные других типов (структур, классов, целых, вещест. переменных).

Знаю, что подобные структуры могут приводить к различным ошибкам при конструировании приложения и его работе. Как можно обойтись без подобных струтур (как их развести)?



вместо void* используй union или struct, как например реализован тип VARIANT

395
03 апреля 2006 года
RelB
367 / / 09.11.2002
Цитата:
Originally posted by AndreySar
вместо void* используй union или struct, как например реализован тип VARIANT


Правильно, вот только struct не советую...

2
03 апреля 2006 года
squirL
5.6K / / 13.08.2003
Цитата:
Originally posted by michael_is_98
Здравствуйте!

Вопрос следующего плана: мне нужно использовать структуру
наподобие
struct
{
int i;
void *data;
};

Т.е. в зависимости от значения члена i член data может указывать на данные других типов (структур, классов, целых, вещест. переменных).

Знаю, что подобные структуры могут приводить к различным ошибкам при конструировании приложения и его работе. Как можно обойтись без подобных струтур (как их развести)?



а я слышал про такую штуку как шаблоны ;)

395
03 апреля 2006 года
RelB
367 / / 09.11.2002
Цитата:
Originally posted by squirL
а я слышал про такую штуку как шаблоны ;)


Шаблоны конечно хорошо, вот только например объеденить структурки с разными типами в массив или т.п. вряд-ли удастся...

3
03 апреля 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by RelB
Шаблоны конечно хорошо, вот только например объеденить структурки с разными типами в массив или т.п. вряд-ли удастся...


Создай для них общий интерфейс и все у тебя удастся.
Без общего интерфейса коллекция объектов бессмыслена.
Для аналогии: предложи контейнер в котором можно хранить сыпучие продукты, жидкости, мысли, радиоволны, гравитационные поля и время.

284
03 апреля 2006 года
michael_is_98
587 / / 25.02.2005
Цитата:
Originally posted by Green
Создай для них общий интерфейс и все у тебя удастся.
Без общего интерфейса коллекция объектов бессмыслена.
Для аналогии: предложи контейнер в котором можно хранить сыпучие продукты, жидкости, мысли, радиоволны, гравитационные поля и время.


Что значит общий интерфейс?
здесь решается следующая задача. На вход лексич. анализатора поступает поток лексем. Все идентификаторы (т.е. переменные или функции) он должен записывать в одну цепочку.
Для функции

 
Код:
typedef struct _op
{  
   int cop;        /* код операции */  
   void (*f)();    /* "отложенное" действие */  
} op;

Для переменной
 
Код:
typedef struct _opd
{  
 int copd;        /* код операнда */  
 double val;      /* значение */  
} opd;

Здесь и возникает задача определит структуру, первый член которой определял бы, что это такое (операнд или операция), второй указывал на структуру типа opd или op.
16K
04 апреля 2006 года
baltika
15 / / 04.04.2006
Тода шаблоны вполне прокатят.
 
Код:
[COLOR=darkblue]
template<class T> class SomeClass {
    int i;
    T *data;
//......................................
};
[/COLOR]
3
04 апреля 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by baltika
Тода шаблоны вполне прокатят.
 
Код:
[COLOR=darkblue]
template<class T> class SomeClass {
    int i;
    T *data;
//......................................
};
[/COLOR]


Так шаблон не прокатит. Нужен общий интерфейс.
Да и по большому счету шаблон тут и не нужен.

Цитата:
Originally posted by baltika

Что значит общий интерфейс?
здесь решается следующая задача. На вход лексич. анализатора поступает поток лексем. Все идентификаторы (т.е. переменные или функции) он должен записывать в одну цепочку.
Для функции


code:


typedef struct _op
{
int cop; /* код операции */
void (*f)(); /* "отложенное" действие */
} op;

Для переменной


code:


typedef struct _opd
{
int copd; /* код операнда */
double val; /* значение */
} opd;

Здесь и возникает задача определит структуру, первый член которой определял бы, что это такое (операнд или операция), второй указывал на структуру типа opd или op.



Общий интерфейс - это то, что логически объединяет эти два типа данных (операцию и операнд). В данном случае их объединяет только одно - код операции/операнда.
Следовательно интерфейс будет выглядеть так:

 
Код:
enum StuffType {OPERATION, OPERAND};

class IOp
{
public:
  StuffType getType() =0;
};

Классы реализующие конкретное наполнение будет выглядеть так:
Код:
class Operation :public IOp
{
public:
  typedef void (*FuncPtr)();

  StuffType getType()   { return OPERATION; }
  FuncPtr getFunction() { return ptr; }

private:
  FuncPtr ptr;
};


class Operand :public IOp
{
public:
  StuffType getType() { return OPERAND; }
  double getData()    { return val; }

private:
  double val;
};

Код, который обрабатывает объекты этих классов выглядит так:
Код:
void processing(IOp* op)
{
  switch(op->getType)
  {
  case OPERATION:
     Operation* operation = static_cast<Operation*>(op);
     operation->getFunction()();
     break;

  case OPERATION:
     Operand* operand = static_cast<Operand*>(op);    
     double data = operation->getData();
     break;
  }
}

Как видишь, никаких void*.
Кстати,
void (*f)(); /* "отложенное" действие */
это не совсем отложенное действие, а скорее указатель на функцию.
Отложенное действие предполагает, что вместе с функцией хранятся и аргументы её вызова. Хотя, здесь аргументов у функции нет, поэтому и не совсем ясно, что это именно. :)
16K
04 апреля 2006 года
baltika
15 / / 04.04.2006
Цитата:
Originally posted by Green Общий интерфейс - это то, что логически объединяет....


Наследовать и от шаблона мона. Кстати

 
Код:
double data = operation->getData();
в case без {} не пройдет наверное :)
3
04 апреля 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by baltika
Наследовать и от шаблона мона. Кстати


1. От шаблона наследовать нельзя, можно наследовать только от уже инстанцированного шаблона.
Причем
template <typename T>
class Child :public Base<T> // это инстанцирование

2. А зачем здесь наследовать от шаблона? Как ты себе представляешь шаблонный интерфейс?

Цитата:
Originally posted by baltika

 
Код:
double data = operation->getData();
в case без {} не пройдет наверное :)


А ты попробуй ;)

16K
04 апреля 2006 года
baltika
15 / / 04.04.2006
1) Смотрим первый пост. Афтар спрашивал как от void* избавится. Шаблоны - это выход.

Цитата:
Originally posted by Green
А ты попробуй ;)


2) Попробовал
error C2360: initialization of 'data' is skipped by 'case' label

3
04 апреля 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by baltika
1) Смотрим первый пост. Афтар спрашивал как от void* избавится. Шаблоны - это выход.


В данном случае это не выход (см. второй пост автора топика)

Цитата:
Originally posted by baltika

2) Попробовал
error C2360: initialization of 'data' is skipped by 'case' label


Значит твой компилятор плохо поддерживает стандарт.
См. 6.7-3:

Цитата:
"It is possible to transfer into a block, but not
in such a way that bypasses declarations with initialization. A program that jumps (note 77) from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer."

284
17 апреля 2006 года
michael_is_98
587 / / 25.02.2005
 
Код:
enum StuffType {OPERATION, OPERAND};

class IOp
{
public:
  StuffType getType() =0;
};

Правильнее, наверное
enum StuffType {OPERATION, OPERAND};

class IOp
{
public:
virtual StuffType getType() =0;
};
3
17 апреля 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by michael_is_98
 
Код:
enum StuffType {OPERATION, OPERAND};

class IOp
{
public:
  StuffType getType() =0;
};

Правильнее, наверное
enum StuffType {OPERATION, OPERAND};

class IOp
{
public:
virtual StuffType getType() =0;
};


А по другому и не получится ;)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог