информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаSpanning Tree Protocol: недокументированное применениеГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Ядро Linux избавляется от российских... 
 20 лет Ubuntu 
 Tailscale окончательно забанила... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
А в чем тогда проблема? 14.07.03 13:32  Число просмотров: 1236
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> В таком случае, если тип нужно заранее указывать, проще
> просто сделать две функции, каждая из которых будет
> работать со своим типом указателя. Просто эти функции будут
> практически идентичны, вот я и хотел упростить их в одну.
Вынеси всю работу, общую для обоих типов в отдельную функцию. А потом доделывай специфичные операции.

> Пишу на С++, но эта функция является методом базового
> класса и вызывается только в методах базового класса.
> Поэтому мне проще сделать две функции, чем усложнять
> структуру класса, создавая лишний абстрактный базовый
> класс.
Дык этот базовый и делай абстрактным. В общепринятой терминологии любой класс, имеющий виртуальные функции называется абстрактным (кажется так), потому как функции использовать уже можно а реализация может появиться уже позже зарелизенного класса.

Короче сделай эту функцию виртуальной, тогда "полем типа" будет vptr - указатель на таблицу виртуальных функций и присваиваться он будет автоматически при создании объекта. А из реализации переопределенной виртуальной функции вызывай общий обработчик (скорее всего он будет реализован в базовом классе), а после этого (или перед этим) делай работу, специфичную для каждого класса.

> Спасибо за советы!
<programming>
неопределенный тип указателя 13.07.03 06:17  
Автор: makeworld Статус: Member
<"чистая" ссылка>
задача такая:
в функцию (или макрос) передается указатель на один из двух возможных типов данных. например:

TYPE1 *t1;
TYPE2 *t2;

func(t1);
func(t2);

сама функция примерно такая:

func(void *ptr) {
//..
}

реально ли внутри функции определить на какой тип данных указывает ptr?

if (sizeof(*ptr) == sizeof(TYPE1)) {
//..
}
else {
//..
}

на подобный код компилятор (VC++) выдает:
error C2100: illegal indirection (оператор * применен не к указателю)
хотя ptr это указатель.
Поле типа, виртуальные функции или RTTI 13.07.03 15:21  
Автор: amirul <Serge> Статус: The Elderman
Отредактировано 13.07.03 15:35  Количество правок: 3
<"чистая" ссылка>
> TYPE1 *t1;
> TYPE2 *t2;
>
> func(t1);
> func(t2);
>
> сама функция примерно такая:
>
> func(void *ptr) {
> //..
> }
>
> реально ли внутри функции определить на какой тип данных
> указывает ptr?
>
> if (sizeof(*ptr) == sizeof(TYPE1)) {
> //..
> }
> else {
> //..
> }
>
> на подобный код компилятор (VC++) выдает:
> error C2100: illegal indirection (оператор * применен не к
> указателю)
> хотя ptr это указатель.
И правильно делает, потому что на момент разыменования этот указатель имеет тип void *. А разыменовывать такие указатели нельзя по определению.

Если тебе необходимо подобное на С, то пожалуй единственное что тебе остается это завести для обоих типов общий заголовок и хранить информацию там:

struct common_header {
    enum type_enum {
        type1,
        type2
    } type;
};

struct MOD_TYPE1 {
    common_header;
    TYPE1 t;
};

struct MOD_TYPE2 {
    common_header;
    TYPE2 t;
};

Делаешь
void
func(common_header *ptr) {
    switch (ptr->type) {
    case common_header::type1: {
        TYPE1 *t1ptr = (TYPE1 *)(ptr + 1);
        // ...
    }
    case common_header::type2: {
        TYPE2 *t2ptr = (TYPE2 *)(ptr + 1);
        // ...
    }
    default:
        // ERROR: unknown type
    }
}

---
Задавать поле типа придется самому при создании объектов:
//...
{
    MOD_TYPE1 t1;
    t1.type = common_header::type1;
    // initializing and using of t1.t
    func((common_header)&t1);
}

---
Ну а если пишешь на C++, то у тебя появляется гораздо более удобный механизм виртуальных функций и RTTI (run-time type information). Хотя есть крайне мало ситуаций, когда RTTI действительно необходим. Уж лучше использовать абстрактный базовый класс, предоставляющий общий интерфейс из виртуальных функций, для обоих типов. А потом работать с указателем на этот абстрактный базовый класс.
Поле типа, виртуальные функции или RTTI 14.07.03 08:53  
Автор: makeworld Статус: Member
Отредактировано 14.07.03 08:54  Количество правок: 1
<"чистая" ссылка>
> Если тебе необходимо подобное на С, то пожалуй единственное
> что тебе остается это завести для обоих типов общий
> заголовок и хранить информацию там:

> Задавать поле типа придется самому при создании объектов:
>
> //...
> {
>     MOD_TYPE1 t1;
>     t1.type = common_header::type1;
>     // initializing and using of t1.t
>     func((common_header)&t1);
> }
> 

---

В таком случае, если тип нужно заранее указывать, проще просто сделать две функции, каждая из которых будет работать со своим типом указателя. Просто эти функции будут практически идентичны, вот я и хотел упростить их в одну.

> Ну а если пишешь на C++, то у тебя появляется гораздо более
> удобный механизм виртуальных функций и RTTI (run-time type
> information). Хотя есть крайне мало ситуаций, когда RTTI
> действительно необходим. Уж лучше использовать абстрактный
> базовый класс, предоставляющий общий интерфейс из
> виртуальных функций, для обоих типов. А потом работать с
> указателем на этот абстрактный базовый класс.

Пишу на С++, но эта функция является методом базового класса и вызывается только в методах базового класса. Поэтому мне проще сделать две функции, чем усложнять структуру класса, создавая лишний абстрактный базовый класс.

Спасибо за советы!
А в чем тогда проблема? 14.07.03 13:32  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> В таком случае, если тип нужно заранее указывать, проще
> просто сделать две функции, каждая из которых будет
> работать со своим типом указателя. Просто эти функции будут
> практически идентичны, вот я и хотел упростить их в одну.
Вынеси всю работу, общую для обоих типов в отдельную функцию. А потом доделывай специфичные операции.

> Пишу на С++, но эта функция является методом базового
> класса и вызывается только в методах базового класса.
> Поэтому мне проще сделать две функции, чем усложнять
> структуру класса, создавая лишний абстрактный базовый
> класс.
Дык этот базовый и делай абстрактным. В общепринятой терминологии любой класс, имеющий виртуальные функции называется абстрактным (кажется так), потому как функции использовать уже можно а реализация может появиться уже позже зарелизенного класса.

Короче сделай эту функцию виртуальной, тогда "полем типа" будет vptr - указатель на таблицу виртуальных функций и присваиваться он будет автоматически при создании объекта. А из реализации переопределенной виртуальной функции вызывай общий обработчик (скорее всего он будет реализован в базовом классе), а после этого (или перед этим) делай работу, специфичную для каждого класса.

> Спасибо за советы!
А в чем тогда проблема? 15.07.03 08:49  
Автор: makeworld Статус: Member
<"чистая" ссылка>
> Дык этот базовый и делай абстрактным. В общепринятой
> терминологии любой класс, имеющий виртуальные функции
> называется абстрактным (кажется так), потому как функции
> использовать уже можно а реализация может появиться уже
> позже зарелизенного класса.

не совсем так. абстрактный класс - класс имеющий чисто виртуальные функции, т.е. не определенные в этом классе. поэтому нельзя создать обьект такого класса.

> Короче сделай эту функцию виртуальной, тогда "полем типа"
> будет vptr - указатель на таблицу виртуальных функций и
> присваиваться он будет автоматически при создании объекта.
> А из реализации переопределенной виртуальной функции
> вызывай общий обработчик (скорее всего он будет реализован
> в базовом классе), а после этого (или перед этим) делай
> работу, специфичную для каждого класса.

написал два макроса, изменил структуру класса так, что теперь эти функции вызываются только в конструкторах и методах того класса, с указателями которого работают. так что теперь неоднозначности нет.
я, кстати, раньше думал, что чисто виртуальные функции нельзя использовать в базовом классе. я ошибался -) щас попробовал - все ок. если бы функции были большие и их нельзя было оформить как макросы сделал бы так как ты предложил. а так с макросами увеличение быстродействия.. теоретическое -)
А inline вместо макросов? :-) 15.07.03 14:00  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> не совсем так. абстрактный класс - класс имеющий чисто
> виртуальные функции, т.е. не определенные в этом классе.
> поэтому нельзя создать обьект такого класса.
Да прогнал. Теперь вспомнил.

> написал два макроса, изменил структуру класса так, что
> теперь эти функции вызываются только в конструкторах и
> методах того класса, с указателями которого работают. так
> что теперь неоднозначности нет.
И кста, если при вызове функции всегда известен тип объекта, то можно и без виртуальных функций - просто переопределить методы. А если сделать их инлайново, то можно избавиться от потенциально опасных макросов (ну там проверка типов, полностью видный текст и т.д.)

> я, кстати, раньше думал, что чисто виртуальные функции
> нельзя использовать в базовом классе. я ошибался -) щас
> попробовал - все ок. если бы функции были большие и их
> нельзя было оформить как макросы сделал бы так как ты
> предложил. а так с макросами увеличение быстродействия..
> теоретическое -)
А я некоторое время думал, что на виртуальные функции нельзя брать указатели - тоже ошибался :-)
Или ещё вариант... 14.07.03 11:33  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
> В таком случае, если тип нужно заранее указывать, проще
> просто сделать две функции, каждая из которых будет
> работать со своим типом указателя. Просто эти функции будут
> практически идентичны, вот я и хотел упростить их в одну.
Если вызывая свою функцию, ты точно знаешь, что это за тип, то можно толкать в функцию кроме указателя ещё одну переменную, которая говорит что за тип.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach