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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Область видимости вложенных классов, достучаться до родителя через указатель 
V
    Опции темы
SABROG
Дата 15.3.2008, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Есть вот такой класс:

Код

class A
{
public:
A();
~A();
    class B
    {
    public:
        B();
        ~B();
        class C
        {
        public:
            C();
            ~C();
        }
    }
int var;
}


У меня в наличии только указатель на класс C. Как по этому указателю получить доступ к var ? Если я правильно понимаю, то вся эта вложенность классов не является наследованием и ни у одного из этих классов нет базового класса.

Такое вот не прокатывает, т.к. требуется наследование:

Код

A::B::C *p = &метод_который_возвращает_ссылку();
p->A::var = 1;


error: `A' is not a base of `A::B::C'

Зачем мне это надо. Хочу построить дерево с ограниченной глубиной, но чтобы не пришлось заводить переменную типа parent и была возможность возвращаться по дереву вверх.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 15.3.2008, 22:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Класс C знает о существовании класса A, но объект класса С о соответствующем объекте класса А не знает. Тебе придется заводить parent.
PM   Вверх
SABROG
Дата 15.3.2008, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(bsa @ 15.3.2008,  22:04)
Класс C знает о существовании класса A, но объект класса С о соответствующем объекте класса А не знает. Тебе придется заводить parent.

Да, заподло, думал удасться через метод получить переменную, не тут то было

error: invalid use of nonstatic data member


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
maxim1000
Дата 15.3.2008, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



когда в описании класса пишется "int a", это означает, что каждый объект класса A будет содержать свою переменную "a"
теперь вопрос: к переменной "a" какого объекта ты хочешь получить доступ?

Это сообщение отредактировал(а) maxim1000 - 15.3.2008, 23:23


--------------------
qqq
PM WWW   Вверх
SABROG
Дата 15.3.2008, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



С чего бы это каждому классу держать свою переменную a, если каждый из них базовый и никто никого не наследует ? Другое дело, что области видимости ограничены и вызов конструктора порождает вызов конструкторов классов, которые являются членами, но не потомками.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
maxim1000
Дата 16.3.2008, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(SABROG @  15.3.2008,  23:54 Найти цитируемый пост)
С чего бы это каждому классу держать свою переменную a

нет, каждый объект содержит переменную "a", не класс

Код

{
    A x,y;//создание двух объектов класса A
    x.a=1;//доступ к переменной "a" объекта "x"
    y.a=2;//доступ к переменной "a" объекта "y"
}

в этом примере x.a и y.a - две разные переменные


--------------------
qqq
PM WWW   Вверх
comcon1
Дата 16.3.2008, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



Без parent - никак)) классу надо где-то хранить, чья он ветка дерева. Если это критично для оптимизации - выложи полный код, тебе помогут, где чО соптимизировать в другом месте.

ты можешь "достучаться" до var, только если объявишь ее static - тогда var будет одна на все экземпляры класса A и к ней можно будет обращаться как A::var. Вот. А по сабжу чем тебе не угодила структурка с parent:
Код

class A {
  private:
   int level;
   A* parent;
  public:
   explicit A(A* par): parent(par), level(par->getLevel()+1) { assert(level<3); }
   A(): parent(NULL), level(0) {;}
   int getLevel() const {return level;}
   A* getParent() const {return parent; }
   int var;
}

// ....

A point();
A p1(&point);
A p2(&point);
A p11(&p1);
p11.getParent()->getParent()->var;


можно, если поломать голову, сделать так, чтобы глубина потомков проверялась на уровне компиляции, но код намного сложнее бует.

Это сообщение отредактировал(а) comcon1 - 16.3.2008, 00:49


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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



преждевременная оптимизация очень вредна  smile 
PM   Вверх
SABROG
Дата 16.3.2008, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Да, я смотрю тот еще геморрой. Поэтому пытаюсь перепроектировать классы. У меня сейчас есть класс, который содержит членом другой класс, а в нем около 20 своих членов, которые надо инициализировать. Через конструктор 20 параметров, я естественно, передавать не собираюсь, а потому инициализирую их вручную построчно. Но проблема в том, что в будущем, доступ на запись этих членов будет только через метод, а внутри обновление полей базы данных, соответственно их надо сделать приватными, но тогда, я не смогу их инициализировать из порождающего класса. Сейчас я прописал его как friend, чтобы получать доступ на запись не через методы для первичной инициализации. Есть еще мысль передать указатель на источник данных через конструктор, чтобы класс сам себя инициализировал, тогда friend не нужен. Как лучше поступить ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 16.3.2008, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



SABROG, изменить дизайн. ты где-то очень серьезно накосячил, вот и возникают проблемы.
Как вариант, можно сделать инициализацию структурой - конструктору передается указатель на нее.
PM   Вверх
SABROG
Дата 16.3.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(bsa @ 16.3.2008,  13:09)
SABROG, изменить дизайн. ты где-то очень серьезно накосячил, вот и возникают проблемы.
Как вариант, можно сделать инициализацию структурой - конструктору передается указатель на нее.

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

Код

A *p = new A;
p->note = получить_значение_столбца_с_именем("описание");
p->type = получить_значение_столбца_с_именем("тип");
...
и т.д. по 20 столбцам


Просто какой смысл тогда делать так?:

Код

struct sA
{
string note;
int type;
};
oA *poA = new poA;
poA->note = получить_значение_столбца_с_именем("описание");
poA->type = получить_значение_столбца_с_именем("тип");
A *p = new A(poA);
...
и т.д. по 20 столбцам




--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 17.3.2008, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



так делать - никакого смысла.
Обычно, если структура содержит много полей, то это скорее всего просто неверно. Хотя бывают некоторые исключения. Например, когда для рассчета какого-то процесса требуется много входных данных. Чаще всего, эти данные - константы (читай настройки), которые берутся, например, из файла. Соответственно, должна быть одна функция, которая тупо загружает эту структуру и все.
В твоем случае, это не похоже на расчет сложного процесса. Неужели где-то требуются все данные сразу? Вряд ли. Соответственно, надо перегруппировать для начала. А там, возможно, и разделить.

Вобщем, я так думаю...
PM   Вверх
SABROG
Дата 17.3.2008, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(bsa @  17.3.2008,  00:04 Найти цитируемый пост)
В твоем случае, это не похоже на расчет сложного процесса. Неужели где-то требуются все данные сразу?


Я кеширую базу данных размером в 10 мегабайт. А насчет расчета. Процесс может и не сложный, но на выходе будет до 1 миллиона цифр, и их формирование будет зависеть как раз от данных в базе. Если данные не будут предварительно загружены в память, то можно сразу 1 миллион умножать на количество запросов к базе данных...


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
comcon1
Дата 17.3.2008, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



Может быть приоткроешь задачу немного подробнее, а то на договорках сложно посоветовать тебе ту или иную модель. Наверняка мы что-нибудь придумаем smile  smile  smile  smile  smile 


--------------------
PM MAIL   Вверх
bsa
Дата 17.3.2008, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



SABROG, база данных, обычно, выглядит как несколько таблиц с наборами значений в каждой. Неужели в каждой таблице куча столбцов?
PM   Вверх
SABROG
Дата 17.3.2008, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



36 таблиц, в среднем по 10 столбцов в каждой. В одной, самой главной, около 20.

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

База данных это справочник где содержатся такие вещи как страны, города, варианты туров, номера, размещения в отелях, рейсы, аиропорты и т.д.

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

ИмяОтеля|Бассейн|Фен в номере|Бильярд|Корт и т.д. до бесконечности

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

Теперь насчет цифры в 1 миллион. Это цены, которые могут быть просчитаны на сезон вперед, где-нибудь с 20 апреля до 31 августа. Несложная операция вычисления это добавление комиссии нашей фирмы. Причем говоря об 1 миллионе я говорю о количестве строк, где количество столбцов (ключи отеля, номер, размещения, питания, ночей, даты и т.д.) тоже будет не маленькое. В итоге все эти цены должны положиться в базу и должен получится 1 excel файл размером в 20-30 мегабайт...

Сейчас это работает так. Есть 200 xml файлов размером по 10 мегабайт, по одному они кладутся через php скрипт во временную таблицу, происходит ручная сортировка, ненужные (непродаваемые) отели выкидываются. Эта процедура занимает 1-2 рабочих дня. Потом процедура на сервере все считает, это около 30 минут. Потом все это селектом выгружается на локальную машину, при этом программа сжирает около 2 гигабайт оперативы. Еще 30 минут. Потом программа формирует excel и т.д.

Я хочу написать свою программу, где указав одну папку программа находит все 200 xml файлов и заносит в таблицу, мне остается нажать "Распарсить" и все это парсится хоть всю ночь, лишь бы небыло моего участия в этом. Далее я просто выделяю мышкой 200 записей в таблице и запускаю процедуру сортировки, которая спрашивает меня о действии только в том случае, если появился какой-нибудь новый отель, номер, размещение и т.д. Если я не отвечаю, сплю например, то программа через 30 секунд игнорирует эту запись и идет обрабатывать дальше. Т.к. я не сделал никакого выбора, то вместо сохранения всего этого в базу ничего не происходит и программа тупо ждет когда приду я. Если вопросов никаких у нее не возникло, то все автоматом сохраняется и начинается просчет. Просчет уже идет на сервере. Но, т.к. у меня на локальной машине есть все эти же данные, то просчет идет и на локальной машине (обычная накидка %) и тут же формируется Excel, минуя 2 гигабайтное сжирание памяти как это есть сейчас и 30 минутное ожидание ответа с сервера.

Фух, устал  smile 


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
comcon1
Дата 17.3.2008, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



Значит грубо структура такая:

Страна 
|
Город
 |        \
Перелет Отель

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

Вот такую хрень оформляешь ввиде обычного дерева:
Страна1 Страна2 Страна3
 |
Город1 Город2 Город3
 |
Отель1 Отель2 Отель3
Код

structure Hotel {
 string Name;
 Town *t;
 HotelData *d;
}

Каждый пункт - структура, информацию в них не хранишь.
Так сказать "СНИМОК ДЕРЕВА".
Далее каждой структуре отеля соответствует структура HotelData, где хранятся все данные. Данные хранятся отдельно, допустим в базе. Из базы данные сериализуются ввиде дампов структур HotelData, допустим, раз в неделю.
Снимок дерева хранится отдельно или тоже загружается из базы (это недолго).

Подсчет. Ты просчитываешь различные туры - это различные обходы дерева. Строишь обход - загружаешь из дампа соответственные данные в память - считаешь. Можно не по одному обходу, а, к примеру по 100 обходам.

Зачем сериализировать? Данные из базы будут браться НАМНОГО медленнее чем сериализированные предварительно.

Вот. Как тебе такой вариант??


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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



с таблицей описания отеля вся понятно. там по сути только два поля - название и булевый массив фиксированного размера. Соответственно, конструктор структуры (один из) грузит данные из базы.
В остальных таблицах, я так понимаю, данных будет меньше и их можно будет легко упаковать в стройные структуры. Возможно, даже аналогичным образом.
PM   Вверх
comcon1
Дата 17.3.2008, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



Во: зацените иерархию:
Код

class AbstractNode {
 AbstractNode* parent;
 boost::pointer_array<AbstractNode> children;
 int level;
 virtual AbstractStructure *getStructure() = 0;
}

class AbstractStructure {
 std::map<string, pair<bool,double> > parameters;
}

class CountryStructure: public AbstractStructure {
 // тра-ля-ля
}

class Country: public AbstractNode {
  CountryStructure* struct;
  virtual AbstractStructure* getStructure() { return struct; };
}


Таким образом за счет абстрактных классов можно полностью отвязать процедуру расчета стоимости тура от вида дерева классов. Т.е. можно добавлять не только новые экземпляры классов, но и новые классы без изменения процедуры расчета!

код расчета типа такой
Код

vector<AbstractNode*> tour;
//здесь составляем тур
double val = calculate_tour(tour);



Это сообщение отредактировал(а) comcon1 - 17.3.2008, 14:02


--------------------
PM MAIL   Вверх
SABROG
Дата 17.3.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Хех, нет вот как раз о запаковывании придется забыть. Так и знал, что привяжетесь к однотипности данных. Но нет, там помимо этого есть столбцы с адресом отеля, телефоном, факсом, e-mailом, сайтом, дополнительным описанием, фотографиями, ссылка на звездность и питание.

Количество записей в справочнике в зависимости от таблицы. Отелей - 3000, номером 17000, 50 стран, 2500 самолетов, 5000 партнеров (у них тоже дофига столбцов). В общем все это укладывается в 10 мегабайт.

Дерево я выстраиваю по зависимостям. В общем вопрос то простой был, надо ли прописать friend классу, чтобы сделать первичную инициализацию членов или лучше передать указатель this на родителя, чтобы класс мог сам проинициализироваться средствами (ссылки на объекты других таблиц/классов, источник базы данных) пораждающего класса.

Схематично это выглядит так.

Код

class БазаДанных
{
public:
list<Отели *>Hotels;
list<Страны *>Countries;
...
    БазаДанных()
    {
        while(sqlRecords->hashNext())
        {
            Отели *hotel= new Отели;
            hotel->name = получить_значение_по_имени_столбца("name");
            ...
            Hotels.append(hotel);
        }
        while(sqlRecords->hashNext())
        {
            Страны *hotel= new Страны;
            country->name = получить_значение_по_имени_столбца("name");
            ...
            Countries.append(hotel);
        }
    };
    ~БазаДанных();

private:
    class Отели
    {
    public:
        Отели();
        ~Отели();
        string name() {return имя;};
        void setName(string &name) {Страны::name = name;Обновляем_Запись_в_SQL_базе_данных("UPDATE hotels SET name='%s';", name)};
    private:
    string имя;
    ...
    };
    class Страны
    {
    public:
        string name() {return имя;};
        void setName(string &name) {Страны::name = name;Обновляем_Запись_в_SQL_базе_данных("UPDATE countries SET name='%s';", name)};
    private:
    string имя;
    ...
    };
}


В итоге обращение к таблицам сводится к database->Hotels(345)->name();

Я хоть и изобразил схематично, но становится понятной проблема, там где конструктор БазаДанных компилятор выдаст ошибку, что обращение идет к приватному члену, а через setName я достучаться не могу, т.к. просто тупо обновлю базу данных тем же значением. Вот и думаю сделать через friend или еще как-то...


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
comcon1
Дата 17.3.2008, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



здесь тебе нужен доступ не ко всем приватам. Может сделать интерфейсную внешнюю дружественную функцию?



--------------------
PM MAIL   Вверх
SABROG
Дата 17.3.2008, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(comcon1 @ 17.3.2008,  15:08)
здесь тебе нужен доступ не ко всем приватам. Может сделать интерфейсную внешнюю дружественную функцию?

Значит надо сделать конструктор БазыДанных другом. 

Код

    class Отель
    {
        friend БазаДанных::БазаДанных();


Такой подходят нормальный или есть еще мнения ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
comcon1
Дата 17.3.2008, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



ну вроде как да. вероятность ошибок низка. только одна друг-функция.


--------------------
PM MAIL   Вверх
SABROG
Дата 18.3.2008, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Возникла другая проблема. У меня ведь 36 таблиц, каждая таблица это класс, а каждому классу надо прописывать френда:

Код

class Отель
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Город
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Отель
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Самолет
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Отель
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Звездность
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Отель
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
class Партнеры
{
friend БазаДанных::БазаДанных();
friend БазаДанных::~БазаДанных();
private:
}
и т.д. 


Пытался наследовать дружбу с базового класса, а она оказывается не наследуется...


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
comcon1
Дата 18.3.2008, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

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



вставляешь в каждый класс дефайн.
Код

#define MUSTBEFRIEND friend БазаДанных::БазаДанных();\
friend БазаДанных::~БазаДанных();



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


Опытный
**


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

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



Цитата(SABROG)

Количество записей в справочнике в зависимости от таблицы. Отелей - 3000, номером 17000, 50 стран, 2500 самолетов, 5000 партнеров (у них тоже дофига столбцов). В общем все это укладывается в 10 мегабайт.

Дерево я выстраиваю по зависимостям.

В стране есть город (в него прилетает самолёт и есть отель(в отеле есть номеры)).

А у тебя всё в куче, какие-то города страны 36 таблиц что куда непонятно, поэтому ты и сформулировать не можешь скока вешать.
PM MAIL   Вверх
SABROG
Дата 18.3.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(inside_pointer @ 18.3.2008,  13:27)
Цитата(SABROG)

Количество записей в справочнике в зависимости от таблицы. Отелей - 3000, номером 17000, 50 стран, 2500 самолетов, 5000 партнеров (у них тоже дофига столбцов). В общем все это укладывается в 10 мегабайт.

Дерево я выстраиваю по зависимостям.

В стране есть город (в него прилетает самолёт и есть отель(в отеле есть номеры)).

А у тебя всё в куче, какие-то города страны 36 таблиц что куда непонятно, поэтому ты и сформулировать не можешь скока вешать.

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

В базе нет привязок типа Отель-Питание-Номер-Размещение. Там многое идет раздельно и увязать это друг с другом я никак не могу. Хотя отели по веткам страны->регионы->города наверно рассортирую.
Самолеты наверное тоже удасться рассортировать, они имеют параметр Порт, который завязан на Городе, а город уже на регионе и стране.

Кстати это не избавит от 36 классов, т.к. каждый класс имеет свои методы.

Это сообщение отредактировал(а) SABROG - 18.3.2008, 15:10


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
inside_pointer
Дата 19.3.2008, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(SABROG)

Я пытаюсь хотябы часть ее функционала перенести в свою программу

А у тебя не построено дерево, тебе надо построить общее дерево для всех данных, на бумаге чтобы всё входило, а потом реализовать его в программе.

Цитата(SABROG)

Хотя отели по веткам страны->регионы->города наверно рассортирую.
Самолеты наверное тоже удасться рассортировать, они имеют параметр Порт, который завязан на Городе, а город уже на регионе и стране.

А на самолётах человеки летают, а на тех на которых никто не летает(например если у тебя там просто список вообще всевозможных рейсов), может летать нулевой человек.

Цитата(SABROG)

Там многое идет раздельно и увязать это друг с другом я никак не могу.

А в жизни они как связаны(создай такой элемент).

Цитата(SABROG)

Кстати это не избавит от 36 классов, т.к. каждый класс имеет свои методы.

Предлагаю обрабатывать данные внешней функцией.

Т.е. просто идёт структура, а обрабатывает эту структуру снаружи одна две функции.
PM MAIL   Вверх
SABROG
Дата 19.3.2008, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Я немного пересмотрел проектирование классов, реально будут менятся всего 4 таблицы, т.к. остальные 32 буду исключительно читаться, а я об этом как-то забыл, по сути это кэши. Поэтому 32 обычные struct и 4 класса, а для 4х классов френды это нормально. Сейчас возникла иная проблема, некоторые поля в базе могут быть пустыми и не ссылаться на какие-либо данные, т.е. это те колонки, где пользователь сам делает выбор. В итоге некоторые ссылки оказываются "битыми", что вызывает краш системы. Чтобы этого избежать мне придется каждый раз проверять ссылку на NULL только для некоторых из колонок, только человек не программа и может забыть это сделать. Надо глянуть в сторону ассертов.

Кстати такая практика доступа к приватным членам на чтение является популярной или я намутил и компилятор сам бы оптимизировал так, чтобы метод не вызывался call'ом, а просто передавалась ссылка ?

Код

public:
inline stour * getTour() const {return Tour;};
    private:
     stour *Tour;


Это сообщение отредактировал(а) SABROG - 19.3.2008, 09:55


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 19.3.2008, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



компилятор сам оптимизирует даже если ты пропустишь inline. Только оптимизацию нужно включить.  smile 
PM   Вверх
SABROG
Дата 19.3.2008, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(bsa @ 19.3.2008,  11:40)
компилятор сам оптимизирует даже если ты пропустишь inline. Только оптимизацию нужно включить.  smile

Нее, лучше взять за правило не надеятся на компилятор. Мало ли придется писать библиотеку какую-нибудь, а юзер начнет собирать ее без оптимизации...

Еще вопрос насчет const, т.е. я указал компилятору, что метод не меняет состояния класса, а зачем компилятору вообще это надо, знать изменилось состояние или нет ? И еще, будет не лишним добавить второй const на указатель, чтобы нельзя его было изменить или это ничего не даст ?

Код

public:
inline const stour * getTour() const {return Tour;};
    private:
     stour *Tour;



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 19.3.2008, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



inline - вообще ничего не гарантирует. Даже если она стоит, а оптимизация отключена, то компилятор ничего не заинлайнит.

Добавлено через 49 секунд
const нужен не компилятору (хотя, ему тоже это может помочь оптимизировать код), а тебе. Это дополнительная степень защиты.
PM   Вверх
SABROG
Дата 19.3.2008, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(bsa @ 19.3.2008,  12:50)
inline - вообще ничего не гарантирует. Даже если она стоит, а оптимизация отключена, то компилятор ничего не заинлайнит.

Добавлено @ 12:51
const нужен не компилятору (хотя, ему тоже это может помочь оптимизировать код), а тебе. Это дополнительная степень защиты.

Это относится к стандарту или к игнорированию его конкретными компиляторами ?

Насчет const после круглых скобок функции я не понял, если это гарантирует, что  внутреннее состояние не изменится, то зачем оно нужно вообще это "внутреннее состояние" ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 19.3.2008, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



const после списка аргументов метода относится к указателю this. Если есть этот модификатор, то компилятор отматерит тебя при попытке изменить любой атрибут объекта или вызвать любой другой неконстантный метод этого класса.
PM   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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