Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> правомерно ли такое 
V
    Опции темы
borisbn
Дата 1.7.2012, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Здравствуйте.

Имеется статический массив объектов
Код
Object s_objects[ I ][ J ][ K ];

Object наследуется от интерфейса IFace
Код

class IFace {
public:
    virtual void foo() = 0;
};
class Object : public IFace {
public:
    virtual void foo();
};

В функции Object::foo() мне нужно узнать свои индексы в массиве s_objects. Делаю я это так
Код
void Object::foo() {
    int idx = this - &s_objects[ 0 ][ 0 ][ 0 ];    // <----- это - нормально ???
    int k = idx % K;
    int j = ( idx / K ) % J;
    int i = ( idx / k / J ) % I;
}

Меня терзают смутные сомнения:
- правомерна ли такая запись ?
- будет ли это работать на всех платформах, на всех компиляторах, при всех настройках компиляции ?
Ещё меня смущает, что Object::foo() будет вызываться из кода, который знает только о IFace. Т.е. как-то так
Код
IFace * p = &s_objects[ i ][ j ][ k ];
p->foo();


Заранее спасибо.

P.S. Хранить в Object свои индексы - не предлагать, т.к. этих объектов будет огромное количество (суммарно более 4 ГБ) и увеличивать класс на 3 int'а я уже не могу.

Добавлено через 5 минут и 50 секунд
P.P.S. А может кто-нибудь подскажет мне в связанной с этим вопросом теме - http://forum.vingrad.ru/forum/topic-353079.html ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Randajad
Дата 1.7.2012, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Правомерно.
PM MAIL   Вверх
volatile
Дата 1.7.2012, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



borisbn, а какова необходимость именно в непрерывном массиве?

То что ваш код, приведенный здесь, будет работать только при непрерывном массиве, это понятно.
Есть ли какие -то другие веские причины, почему нужен именно непрерывный массив.
Если веских причин в непрерывном массиве нет, то решится первая проблема
Цитата(borisbn @  1.7.2012,  11:00 Найти цитируемый пост)
 в связанной с этим вопросом теме 

и будем решать эту. (чуток по другому).

зы: в любом случае (непрерывный или прерывный),  синтаксис будет одинаков: objects [i][j][k];

PM MAIL   Вверх
borisbn
Дата 1.7.2012, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(volatile @  1.7.2012,  13:36 Найти цитируемый пост)
какова необходимость именно в непрерывном массиве?

В принципе, необходимости нет. Однако, я бы хотел, чтобы получение этих индексов было бы максимально быстрое, поэтому и сделал массив непрерывным.
В общем, суть задачи такова:
1) мне заранее известно количество этих объектов (а именно: кол-во строк, столбцов и ... как бы обозвать... кол-во таблиц)
2) в функции foo() мне необходимо знать № таблицы, № строки и № столбца объекта, у которого эта foo() вызвана
3) хранить эти индексы в объекте я не могу (и так много памяти кушаю)

P.S. я бы хотел на этапе компиляции/линковки знать, что память будет выделена. Не хотелось бы узнать о нехватке памяти в рантайме...

Цитата(volatile @  1.7.2012,  13:36 Найти цитируемый пост)
в любом случае (непрерывный или прерывный),  синтаксис будет одинаков: objects [i][j][k];

у меня как раз обратная задача - по имеющемуся указателю вычислить i, j и k 

Это сообщение отредактировал(а) borisbn - 1.7.2012, 13:54


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 1.7.2012, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(borisbn @  1.7.2012,  13:54 Найти цитируемый пост)
по имеющемуся указателю вычислить i, j и k 

borisbn, я чуток подумал. Действительно вычислить индекс по адресу, можно оптимально только при непрерывном массиве.
Вначале думал просто сделать массив указателей на указатели на s_objects []
Но там вычисление индексов будет не простым.
Понадобится что-то типа двух дополнительных индексов (map'ов) , размерами один I, другой J. (впрочем это относительно не много) + время на доступ к этим мапам.

В общем, не знаю. Как крайний вариант, если не выйдет выделить весь массив сразу,
могу накалякать версию с двумя мапами. Если хотите.
Или вас это в принципе не устроит?


Это сообщение отредактировал(а) volatile - 1.7.2012, 16:04
PM MAIL   Вверх
borisbn
Дата 1.7.2012, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(volatile @  1.7.2012,  15:57 Найти цитируемый пост)
могу накалякать версию с двумя мапами. Если хотите.
Или вас это в принципе не устроит?

спасибо, но я думаю, что справлюсь ))
Что ж... раз все считают такую конструкцию правомерной, то ИМХО нечего выдумывать... оставлю так. Единственное, что меня беспокоит, так это то, что мне могут просто не дать выделить такой большой массив в статической памяти...
Хотя... не беда. Я ж могу и в динамической памяти выделить непрерывный участок... Опять же - если дадут.
Всем спасибо. Закрываю, но хотелось бы услышать советы по соседней теме - http://forum.vingrad.ru/forum/topic-353079.html


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 1.7.2012, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(borisbn @  1.7.2012,  16:33 Найти цитируемый пост)
спасибо, но я думаю, что справлюсь ))

ок.

Цитата(borisbn @  1.7.2012,  11:00 Найти цитируемый пост)
    int i = ( idx / k / J ) % I;

это конечно опечатка, но вдруг вы не заметили
 k  K

PM MAIL   Вверх
Randajad
Дата 1.7.2012, 17:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Цитата

P.S. я бы хотел на этапе компиляции/линковки знать, что память будет выделена. 


Такого не бывает. Все узнается только в рантайме. Даже если линкер и запишет размер памяти, которая нужна, не факт, что OS при запуске вашей программы не пошлет ее далеко.
PM MAIL   Вверх
volatile
Дата 1.7.2012, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(Randajad @  1.7.2012,  17:54 Найти цитируемый пост)
Такого не бывает.

Randajad, borisbn просто не совсем точно выразился. 
в соседней темке, он объяснил
Цитата(borisbn @  1.7.2012,  14:33 Найти цитируемый пост)
Я, пожалуй, неправильно высказался... Я НЕ хочу в своей программе проверять, выделилась ли память после new. Я хочу, чтобы стандартный загрузчик без моего участия либо выделил память и дал бы моей программе работать, либо сам бы ругнулся на недостаток памяти 



Это сообщение отредактировал(а) volatile - 1.7.2012, 18:52
PM MAIL   Вверх
mes
Дата 1.7.2012, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  1.7.2012,  10:00 Найти цитируемый пост)
- будет ли это работать на всех платформах, на всех компиляторах, при всех настройках компиляции ?

при множественном наследовании не всегда..

Добавлено через 5 минут и 57 секунд
Цитата(borisbn @  1.7.2012,  12:54 Найти цитируемый пост)
1) мне заранее известно количество этих объектов (а именно: кол-во строк, столбцов и ... как бы обозвать... кол-во таблиц)


Цитата(borisbn @  1.7.2012,  10:00 Найти цитируемый пост)
IFace * p = &s_objects[ i ][ j ][ k ];
p->foo();

почему бы не так :
Код

void foo(.. i, .. j, .. k)
{
  if ( IFace * p = &s_objects[ i ][ j ][ k ];)
     p->foo(j,i,k);
}

foo(i,j,k);



Добавлено через 10 минут и 58 секунд
Цитата(borisbn @  1.7.2012,  10:00 Найти цитируемый пост)
P.S. Хранить в Object свои индексы - не предлагать, т.к. этих объектов будет огромное количество (суммарно более 4 ГБ) и увеличивать класс на 3 int'а я уже не могу.

а нужно ли хранить сами обьекты, может приспособленца (flyweight pattern) взять в помощь ?


--------------------
PM MAIL WWW   Вверх
math64
Дата 2.7.2012, 07:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Код

struct ObjectData { ... };
ObjectData data[I][J][K];
class Object : publc IFace {
public:
Object(int _i, int _j, int _k) : i(_i), j(_j), k(_k) { pdata = &data[i][j][k]; }
void foo();
private:
ObjectData* pdata;
int i,j,k;
}

void foo() {
for(int i =0; i < I; i++)
  for(int j =0; j < J; j++)
    for(int k =0; k < K; k++) {
       Object o(i,j,k);
       IFace* iface = &o;
       iface->foo();
    }
}

Потребности в памяти уменьшатся - в ObjectData не будет указателя на таблицу виртуальных методов, но потеряешь в скорости (на каждом обороте цикла объект создаётся заново)

PM   Вверх
borisbn
Дата 2.7.2012, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(volatile @  1.7.2012,  16:45 Найти цитируемый пост)
это конечно опечатка

 smile
как Вы понимаете, в настоящей программе у меня переменные немного по-другому называются  smile 

Цитата(mes @  1.7.2012,  19:07 Найти цитируемый пост)
при множественном наследовании не всегда..

ясно. спасибо. учту.
Цитата(mes @  1.7.2012,  19:07 Найти цитируемый пост)
почему бы не так :

на самом деле, тот, кто вызывает foo() ничего об этом статическом массиве не знает. У него есть только указатель, да и то на базовый класс.

Цитата(mes @  1.7.2012,  19:07 Найти цитируемый пост)
а нужно ли хранить сами обьекты, может приспособленца (flyweight pattern) взять в помощь ?

первый раз слышу. /me пошёл читать про flyweight pattern

math64
Цитата(borisbn @  1.7.2012,  11:00 Найти цитируемый пост)
Хранить в Object свои индексы - не предлагать, т.к. этих объектов будет огромное количество (суммарно более 4 ГБ) и увеличивать класс на 3 int'а я уже не могу.


Добавлено через 12 минут и 14 секунд
Цитата(borisbn @  2.7.2012,  08:33 Найти цитируемый пост)
/me пошёл читать про flyweight pattern

Кажется, не подойдёт, т.к. я не хочу выделять память под каждый объект из-за накладных расходов.
вот - http://fahrenheit2539.blogspot.com/2012/05...ield-study.html - недавно прочитал про накладные расходы в new и ужаснулся... оттуда и задумался о большом статическом массиве


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
math64
Дата 2.7.2012, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



http://en.wikipedia.org/wiki/Flyweight_pattern
borisbn, В моём варианте Object - временный объект (ну, чтобы удовлетворить Вашему требованию переименуем его в XObject), в приведённом мной цикле он существует в одном экземляре внутри цикла, добавленние в него индексов не увеличивает потребление памяти в программе, а за счёт того, что в большом массиве будет не объект, а структрура без таблицы виртуальных методов (её можно ещё упаковать, если возможно), потребление памяти уменьшается. Но объект нужно конструировать каждый раз заново, когда он понадобится и удалять по ненадобности (данные, по которым можно восстановить объект, сохраняются) - скорость выполнения уменьшится. Это тоже паттерн проектирования, но как он называется, не помню.
PM   Вверх
math64
Дата 2.7.2012, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Почитал про FlyWeightPattern - фактически, мой код - его упрощенная версия, new, как видите, не обязателен. Важно выделить из объекта упакованные данные, по которым всегда можно восстановить объект и тогда объект нужно создавать только тогда, когда он нужен для работы.
PM   Вверх
mes
Дата 2.7.2012, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  2.7.2012,  07:33 Найти цитируемый пост)
Кажется, не подойдёт, т.к. я не хочу выделять память под каждый объект из-за накладных расходов.

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

Цитата(borisbn @  2.7.2012,  07:33 Найти цитируемый пост)
недавно прочитал про накладные расходы в new и ужаснулся... оттуда и задумался о большом статическом массиве 

опять игра слов.. статический массив или массив в статической памяти smile.. 


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1035 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.