Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > C++, инициализация вложенной структуры


Автор: vadiml 15.10.2007, 10:19
Я создаю класс MyClass, потомка PrevClass, в котором есть структура:
static const Qqqq qqqq;
сама структура описана так:
Код

struct Qqqq {
    /* куча функций, но конструктора нет */
    struct {
        const Qqqq *prev;
        const char * str;
        const int *data;
    } d;
}


сейчас эта структура инициализируется как
Код

const Qqqq MyClass::qqqq = {
    { &PrevClass::qqqq, stringdata_MyClass, meta_data_MyClass }
};


Я хочу убрать из определения этой структуры static и инициализировать её в конструкторе, чтоб у каждого экземпляра класса был свой вариант:
Код

MyClass::MyClass ()
 : PrevClass(), qqqq( /*???*/ )
{

}

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

Что можно попробовать или где такое описано?

Автор: archimed7592 15.10.2007, 10:29
Вообще нихрена не понятно: то ли ты хочешь убрать static(откуда? зачем он там вообще нужен был?), то ли ты уже убрал, но рассказываешь так, будто он там есть...

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

Цитата(vadiml @  15.10.2007,  10:19 Найти цитируемый пост)
MyClass::MyClass ()
 : PrevClass(), qqqq( /*???*/ )
{
}

Код


namespace
{
    const Qqqq &getQqqq()
    {
        static const Qqqq qqqq = { /* ... */ };
        return qqqq
    }
}

MyClass::MyClass ()
 : PrevClass(), qqqq(getQqqq())
{
    /* ... */
}

Автор: vadiml 15.10.2007, 11:26
названия не секретные, они длинные smile

а getQqqq() -- не подходит, т.к. здесь обращение к static  const Qqqq. А мне надо разные экземпляры Qqqq() для разных экземпляров класса MyClass. 

Один общий экземпляр структуры Qqqq и сейчас есть.

Автор: archimed7592 15.10.2007, 11:33
Цитата(vadiml @  15.10.2007,  11:26 Найти цитируемый пост)
а getQqqq() -- не подходит, т.к. здесь обращение к static  const Qqqq. А мне надо для разные Qqqq() для разных экземпляров класса MyClass 

Разные на основании чего? Твой конструктор не принимает аргументов, так что мне сложно одуплить как они могут быть разными, но, тем не менее:
Код

namespace
{
    const Qqqq getQqqq(const A1 a1, const A2 a2, const A3 a3)
    {
        const Qqqq qqqq = { a1, a2, a3 };
        return qqqq
    }
}
MyClass::MyClass ()
 : PrevClass(), qqqq(getQqqq(a1, a2, a3))
{
    /* ... */
}

Что по сути является рукописным конструктором, но, насколько я понимаю, самого конструктора ты пытаешься избежать чтобы сохранить статус структуры POD, так? Если нет, то просто напиши ей конструктор и делай так:
Код

MyClass::MyClass ()
 : PrevClass(), qqqq(a1, a2, a3)
{
    /* ... */
}

Автор: vadiml 16.10.2007, 11:28
насколько я понимаю, самого конструктора ты пытаешься избежать

Я его не пытаюсь избежать, это библиотечный класс (точнее библиотечная структура) без конструктора, но с вложенной структурой.

а
Код

namespace
{
    const Qqqq getQqqq(const A1 a1, const A2 a2, const A3 a3)
    {
        const Qqqq qqqq = { a1, a2, a3 };
        return qqqq
    }
}

помогло, хотя и чуть в другом виде:
Код

namespace  {
    const Qqqq getQqqq(const char *stringdata, const uint *data) {
        const Qqqq q = { { &PrevClass:qqqq, stringdata, data, 0 } };
        return q;
    }
}

наверное вложенную структуру только так и можно инициализировать

Автор: akizelokro 16.10.2007, 12:41
Извини, но условия задачи не совсем понятны (хотя интересны).
Вложенные структуры (например, вложенные классы) ты можешь инициализировать и по-другому. Здесь у тебя главную проблема - то, что вложенная структура идет со спецификатором const, иначе говоря, этот спецификатор требует для нее список инициализации (после этого она становится действительно const), ее нельзя прописать в теле конструктора. Ты можешь прописать список инициализации и в другом виде, но и указанный выше способ  является достаточно корректным.
С учетом того, что компилятор запретит тебе модифицировать const объект, но они включает в себя указатели, ты можешь модифицировать например сами char'ы, которые адресует const char * str.  Это возможно, но является плохим стилем кодирования. Применять не рекомендую (если уж только корректный вариант не устраивает тебя ни в какую, - всякое бывает).

Есть еще один совершенно "отвязный" фортель... Но, не думаю, что он тебе понадобится.

Автор: maxim1000 16.10.2007, 12:56
вообще-то в условии константны не указатели, а данные, на которые они указывают
так что можно без проблем их (указатели) менять в процессе работы...

Автор: archimed7592 16.10.2007, 13:07
Цитата(maxim1000 @  16.10.2007,  12:56 Найти цитируемый пост)
вообще-то в условии константны не указатели, а данные, на которые они указывают
так что можно без проблем их (указатели) менять в процессе работы...


Цитата(vadiml @  15.10.2007,  10:19 Найти цитируемый пост)
static const Qqqq qqqq;

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

Автор: maxim1000 16.10.2007, 13:13
а... недочитал...

Автор: akizelokro 16.10.2007, 14:44
Иными словами, примерный код (откомпилил, вроде работает)

Код

struct Qqqq {
    struct {
        const Qqqq *prev;
        const char * str;
        const int *data;
    } d;
};

char buf[1000];
const Qqqq something(const Qqqq *, const char* str, const int *)
{
    Qqqq q1= {NULL, str, NULL};
    return q1;
};

class MyClass
{
const struct Qqqq qqqq;
public:
MyClass::MyClass():qqqq(something(NULL, (const char *)buf, NULL)) {};
};

int main(int argc, char* argv[])
{
MyClass m;
buf[0] = '\0';

Автор: archimed7592 16.10.2007, 14:55
Цитата(akizelokro @  16.10.2007,  14:44 Найти цитируемый пост)
Иными словами, примерный код (откомпилил, вроде работает)

1. Зачем приводить buf к const char * да ещё и c-style кастом 0_о? Не доверяешь компилятору smile?
2. Что ты этим кодом хотел показать? Я что-то мысль не уловил...

Автор: akizelokro 16.10.2007, 15:10
Цитата

Не доверяешь компилятору


Наоборот, компилятору я доверяю больше, чем себе smile 

Код

Что ты этим кодом хотел показать? Я что-то мысль не уловил...
 

Протормозил. Сегодня дергают, вот я и урывками и мимоходом. Смысла в нем не было, и так понятно.

Автор: vadiml 16.10.2007, 17:45
akizelokro, 

Цитата(akizelokro @  16.10.2007,  14:44 Найти цитируемый пост)
Qqqq q1= {NULL, str, NULL};


вообще-то, как я понял, для вложенной структуры следует писать 
Код

Qqqq q1= { {NULL, str, NULL} };



Автор: archimed7592 16.10.2007, 17:47
Цитата(vadiml @  16.10.2007,  17:45 Найти цитируемый пост)
вообще-то, как я понял, для вложенной структуры следует писать 

Не обязательно smile.

Автор: vadiml 16.10.2007, 17:49
PS если кого интересует, что это за хитрая структура такая, то это QMetaObject из Qt4, а вложенная структура там помечена как private data, а влазить в нее пришлось, чтоб сделать систему сигналов-слотов динамической, т.е. имея одно описание класса, каждый экземпляр мог иметь свои сигналы-слоты и они задавались при инициализации класса.

Автор: akizelokro 17.10.2007, 08:59
Код

Qqqq q1= { {NULL, str, NULL} };

прошу прощения, времени не было и я, соответственно.. накорябал пример как быстрее. smile Скорее всего, это был пример ответа, что данные неконстантны.
А вообщем, можно и сами указатели можно менять через const_cast в любое время.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)