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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пара вопросов про массив хэндлеров, и инициализацию структуры нулевыми знач. 
:(
    Опции темы
SABROG
  Дата 30.4.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



У меня около 30 обычных функций с одной и той же сигнатурой, но разным поведением. Есть общая функция в которую поступает структура, где одно из полей типа int state. В зависимости от этого state я вызываю одну из 30 функций. Писать switch() с 30 case'ами не хочется. Что остается, массив с хендлерами (callback'ами)

Код


typedef void (*StateHandler)(MyStruct* arg);

static const StateHandler[] = {&handlerOne, &handlerTwo, ..., &handlerThirty};

void handlerOne(MyStruct* arg)
{
}
...
void handlerThirty(MyStruct* arg)
{
}

void MyMainFoo(MyStruct* arg)
{
    StateHandler[arg->state](arg);
}


?

Если будут варианты, то хотелось бы на чистом C++ с/без stl. Boost и tr1 не предлагайте, пожалуйста.
---
Есть такая глупость:

Код

struct MyStruct
{
    MyStruct (int arg1 = 0
                           , int arg2 = 0
                           , int arg3 = 0
                           , int arg4 = 0) : m_var1(arg1)
            , m_var2(arg2)
            , m_var3(arg3)
            , m_var4(arg4)
    {}
    int m_var1, m_var2, m_var3, m_var4;
};


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

Код

MyStruct var = {0};
foo(var);


При таком объявлении:

Код

struct MyStruct {
int var1, var2, var3, var4;
};

---
В случае с классом вместо структуры мне достаточно вызвать метод так:

Код

class MyClass
    ...
    method(MyStruct ms = MyStruct());
    ...
};

void MyClass::foo()
{
    method(); // default constructed value MyStruct initialized with 0
}


Как вы могли заметить дизайн структуры гораздо проще и читабельней, но в случае с ней приходится писать много лишнего потом. Вопрос в том, возможно ли инициализировать переменные-члены структуры нулями во время передачи её в качестве default-constructed argument для метода класса? Что-то типа этого:

Код

class MyClass
    ...
    method(MyStruct ms = MyStruct() = {0});
    ...
};



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


Пердупержденный
***


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

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



Если я правильно понял суть сего длинного поста... В структуре можно сделать конструктор и написать в нем:
Код

memset(this,0,sizeof(*this));

Таким образом по умолчанию в в функцию попадет структура, инициализированная нулями.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
SABROG
Дата 30.4.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(djamshud @ 30.4.2010,  12:12)
Если я правильно понял суть сего длинного поста... В структуре можно сделать конструктор и написать в нем:
Код

memset(this,0,sizeof(*this));

Таким образом по умолчанию в в функцию попадет структура, инициализированная нулями.

По этому поводу такой комментарий встретил:

Код

Formally, this triggers undefined behavior according to
the C++ standard - unfortunately.
It is illegal to "overwrite" a non-POD type using memset,
and having a constructor means that Foo is not POD.
There are proposals for C++0x to formally allow this
(by making sub-categories of "POD" types).

In practice, it is likely to behave as expected in this
simple case (memset would obviously be bad if Foo had
a virtual member, or a base class with such a member).

Unfortunately, in the constructor, there is no simple
and portable way to automatically initialize members of
built-in types to a default value. I am not aware of any
formally portable shortcut to avoid the error-prone
listing of every member in the initialization-list:
Foo():a(0),b(0),c(0),d(0),e(0),f(0),g(0),h(0),i(0) ,j(0),k(0){}

However, some compilers or source-checking tools may
provide warnings if only a subset of members is listed
in an initialization-list.



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


Пердупержденный
***


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

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



Там про классы написано с виртуальными методами и сложными данными внутри, как я понял. Структуре с членами-интами и прочими POD-типами ничего не станет, как я считаю, по крайней мере сам применял такой подход неоднократно, и проблем не было.

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

Добавлено через 6 минут
Ну и в догонку, писать больше, но проблем с "плохой инициализацией" не будет:

Код

struct A{
int a;
int b;};

void foo(struct A const &stA=(struct A){0,0}){
printf("a=%d,b=%d\n",stA.a,stA.b);
}



--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
KOHCEPBATOP
Дата 30.4.2010, 12:40 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(djamshud @  30.4.2010,  12:25 Найти цитируемый пост)
Структуре с членами-интами и прочими POD-типами ничего не станет, как я считаю, по крайней мере сам применял такой подход неоднократно, и проблем не было.
Согласен.

Если очень боязно, можно сделать так:
Код

struct MyStruct {
   struct s {
      int var1, var2, var3, var4;
   } v;
   MyStruct(){ZeroMemory(&v,sizeof(v));};
};

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


uploading...
****


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

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



SABROG

Код

struct test
{
    int a;
    int b;
    int c;
};

int main()
{
    test t = test();
    std::cout << t.a << t.b << t.c << std::endl; // все нули
}

может так?

Это сообщение отредактировал(а) azesmcar - 30.4.2010, 12:56
PM   Вверх
SABROG
Дата 30.4.2010, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(azesmcar @  30.4.2010,  12:54 Найти цитируемый пост)
может так?

Разве стандарт гарантирует, что все значения будут инициализированы нулями?

Цитата(djamshud @  30.4.2010,  12:25 Найти цитируемый пост)
Ну и в догонку

Код

(MyStruct) {0, 0, 0, 0}


А этот вариант интересен. Я правильно логику понимаю, тут происходит Си cast безымянного set'a (?) с целочисленными значениями к MyStruct? Аналогично:

Код

void foo(int &arg = (int) {0}) // foo(int arg = 0)
{
}


Тогда странно, что такие варианты не работают:

Код

void foo(int &arg = int({0})) // wrong
{
}

void foo(int &arg = static_cast<int>({0})) // wrong
{
}


Это сообщение отредактировал(а) SABROG - 30.4.2010, 13:46


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


Пердупержденный
***


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

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



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


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
djamshud
Дата 30.4.2010, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


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

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



Удалено по причине: копия

Это сообщение отредактировал(а) djamshud - 30.4.2010, 13:46


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
KOHCEPBATOP
Дата 30.4.2010, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(azesmcar @  30.4.2010,  12:54 Найти цитируемый пост)
может так?

Однозначно - так нельзя!  smile 
PM MAIL   Вверх
SABROG
Дата 30.4.2010, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Похоже это называется анонимной структурой, и с ней похоже тоже не все так гладко: http://stackoverflow.com/questions/177393/...-structure-in-c


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


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


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

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



Цитата(SABROG @  30.4.2010,  12:35 Найти цитируемый пост)
Разве стандарт гарантирует, что все значения будут инициализированы нулями?

ну это смотря кого инициализировать.. может и не нулем  smile

Цитата(SABROG @  30.4.2010,  12:35 Найти цитируемый пост)
Аналогично:

не аналогично.. только константной ссылке можно присваивать временный рвалуе объект..

Добавлено через 4 минуты и 17 секунд
Цитата(djamshud @  30.4.2010,  11:25 Найти цитируемый пост)
Структуре с членами-интами и прочими POD-типами ничего не станет, как я считаю, по крайней мере сам применял такой подход неоднократно, и проблем не было.

отличная аргументация  smile 

Цитата(djamshud @  30.4.2010,  11:25 Найти цитируемый пост)
т.к. те компиляторы, что я я видел, отделяют данные от всего прочего и указать на объект фактически является указателем на поле данных объекта.

а вот хотелось бы поподробней узнать, что имелось ввиду.. 


Это сообщение отредактировал(а) mes - 30.4.2010, 13:52


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


Пердупержденный
***


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

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



>http://stackoverflow.com

Проблема их была в том, что структура была размером в 4 мегабайта и стэк заканчивался из-за ее копии.

>( struct bigstruct ){ 0 }

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


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
SABROG
Дата 30.4.2010, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(mes @  30.4.2010,  13:50 Найти цитируемый пост)
только константной ссылке можно присваивать временный рвалуе объект..

Значит gcc 4.4.1 не следует стандарту? Все компилится и работает без константности.

Цитата(mes @  30.4.2010,  13:50 Найти цитируемый пост)
отличная аргументация

smile надеюсь это была ирония.

Цитата(djamshud @  30.4.2010,  14:01 Найти цитируемый пост)
Проблема их была в том, что структура была размером в 4 мегабайта и стэк заканчивался из-за ее копии.

По иронии название их сайта совпадает с проблемой smile

Ясно. Значит правила все-таки есть. Инициализировать каждый член по отдельности. Добавлять ключевое слово "struct", чтобы оставить совместимость с языком Cи.

Осталось понять насчет константности ссылки и почему static_cast'ом нельзя привести безымянную структуру к нужному типу.

По второму вопросу, с хэндлерами, есть мысли?


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


uploading...
****


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

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



Цитата(KOHCEPBATOP @  30.4.2010,  13:47 Найти цитируемый пост)
Однозначно - так нельзя!  smile  

да ну?
Цитата(mes @  30.4.2010,  13:50 Найти цитируемый пост)
отличная аргументация  smile 


PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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