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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> variadic parameters to base class constructor, передача переодических параметров 
V
    Опции темы
baldina
Дата 29.1.2010, 20:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



InvalidProperty, при помощи синтаксиса С++ данную проблему изящно не решить. ковыряясь только в конструкторах это невозможно.
Однако возник вопрос: что делает конструктор базового класса с переменным числом параметров, тип которых не проверяется в процессе компиляции? вероятно скармливает тому же vsnprintf. Тогда следующий вопрос - зачем классу исключений вообще этим заниматься? пусть конструирует строку тот, кто генерирует исключение, а класс исключения работает с постоянным числом параметров.  Всё, проблемы нет.
Обратите внимание: ваш pack() - совершенно инородный элемент в классе, класс нагружен не свойственным ему функционалом. Разделите функционал и проблема исчезнет.

PM MAIL   Вверх
zim22
Дата 29.1.2010, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(andrew_121 @  29.1.2010,  19:05 Найти цитируемый пост)
ну расскажи что думаешь об этом. меня тоже такая задача посещает время от времени.

вот самый простой вариант. чем не устраивает?
Код

#include "stdafx.h"
#include <iostream>

struct BaseExceptionClass {
  BaseExceptionClass(const char *message) : message_(message) { }
  const char *what() { return message_; }
private:
  const char *message_;
};

struct DerivedExceptionClass : BaseExceptionClass {
  DerivedExceptionClass(const char *message) 
    : BaseExceptionClass(message) { }
};

int _tmain(int argc, _TCHAR* argv[])
{
  const char *text = "superb";
  int number = 88;

  try {
    char buffer[256] = {0};
    sprintf(buffer, "hello, i am %s, %d", text, number);

    throw DerivedExceptionClass(buffer);

  } catch (DerivedExceptionClass &ex) {
    std::cout << ex.what();
  }
  return 0;
}




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


Эксперт
****


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

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



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

предваряя возможную дискуссию о разном числе неких разнотипных свойств, которые надо обрабатывать классу исключения, предложу в этом случае воспользоваться
std::vector <boost::variant> или std::vector <boost::any>.

Добавлено через 3 минуты и 7 секунд
Цитата(zim22 @  29.1.2010,  19:02 Найти цитируемый пост)
Цитата(InvalidProperty @  29.1.2010,  17:58 )
. Нужно, чтобы и дочерний и базовый класс поддерживали конструкцию выбрасывания исключений с переменным числом параметров

это не проблема. это деталь реализации.

 smile 
PM MAIL   Вверх
andrew_121
Дата 29.1.2010, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Цитата(baldina @  29.1.2010,  20:24 Найти цитируемый пост)
Однако возник вопрос: что делает конструктор базового класса с переменным числом параметров, тип которых не проверяется в процессе компиляции? вероятно скармливает тому же vsnprintf. Тогда следующий вопрос - зачем классу исключений вообще этим заниматься? пусть конструирует строку тот, кто генерирует исключение, а класс исключения работает с постоянным числом 

это верно. но наверняка не только мне и InvalidProperty хотелось бы получить такую возможность. и желательно не только строковое сообщение. было бы супер!
пример:
Код

int main() {
   try {
      std::ifstream file(name);
      if ( !file ) {
         throw exception_type("fname %s, error code%d", name, errno);
      }
   } catch(const exception_type& e) {
      std::cout << e.what() << std::endl;
      std::cout << e.func() << std::endl;
      std::cout << e.line() << std::endl;
      std::cout << e.ecode() << std::endl;
   }
   return 0;
}

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


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
baldina
Дата 29.1.2010, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



andrew_121, 

Цитата(baldina @  29.1.2010,  20:29 Найти цитируемый пост)
предваряя возможную дискуссию о разном числе неких разнотипных свойств, которые надо обрабатывать классу исключения, предложу в этом случае воспользоваться
std::vector <boost::variant> или std::vector <boost::any>.


PM MAIL   Вверх
andrew_121
Дата 29.1.2010, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



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

еще думаю для этого подойдет boost.format


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
baldina
Дата 29.1.2010, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



andrew_121, кажется то, что выше, вы не читаете  smile 
PM MAIL   Вверх
andrew_121
Дата 29.1.2010, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Цитата(zim22 @  29.1.2010,  20:26 Найти цитируемый пост)
вот самый простой вариант. чем не устраивает?

этим -
Цитата(zim22 @  29.1.2010,  20:26 Найти цитируемый пост)
sprintf(buffer, "hello, i am %s, %d", text, number);




--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Lazin
Дата 29.1.2010, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



как-же мы любим придумывать несуществующие проблемы и решать их smile 
я, в свою очередь, хочу предложить такой способ решения проблемы передачи переменного числа параметров в конструктор базового класса
file: generate_ctor.ipp
Код

Derived(PARAMETER_DEFINITION_LIST) : Base(PARAMETER_LIST)
{
}
#undef PARAMETER_DEFINITION_LIST
#undef PARAMETER_LIST

other file:
Код

struct Base
{
    Base(int a) { std::cout << "1" << std::endl; }
    Base(int a, int b) { std::cout << "2" << std::endl; }
};

struct Derived : public Base
{
#define PARAMETER_DEFINITION_LIST int a
#define PARAMETER_LIST a
#include "generate_ctor.ipp"

#define PARAMETER_DEFINITION_LIST int a, int b
#define PARAMETER_LIST a, b
#include "generate_ctor.ipp"
};


Цитата(andrew_121 @  29.1.2010,  20:38 Найти цитируемый пост)
это верно. но наверняка не только мне и InvalidProperty хотелось бы получить такую возможность. и желательно не только строковое сообщение. было бы супер!

тогда тебе как-то придется генерировать класс с переменным числом членов и недетерминированым набором методов  smile 
PM MAIL Skype GTalk   Вверх
Lazin
Дата 29.1.2010, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(InvalidProperty @  29.1.2010,  17:40 Найти цитируемый пост)
Код

throw MyDerivedException(MyBaseException::pack("exception N %d", 45));

я не вижу смысла в этом, класс исключения - Copy Constructable, поэтому можно писать так:
Код

throw MyDerivedException(MyBaseException("exception N %d", 45));


 smile 

Это сообщение отредактировал(а) Lazin - 29.1.2010, 21:59
PM MAIL Skype GTalk   Вверх
mes
Дата 29.1.2010, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(InvalidProperty @  29.1.2010,  16:56 Найти цитируемый пост)
mes, вторым постом я привел строку, которую можно использовать, применив данный метод

тогда Вы неправильно поняли мое непонимание. Меня интересовала именно задача, а не неполучающийся способ ее реализовать.
Ну вообщем тут уже много ответили, но еще раз проакцентирую внимание:
Цитата(zim22 @  29.1.2010,  18:48 Найти цитируемый пост)
не нужно решать задачу неправильными методами.
чтобы узнать какой метод правильный - нужно сначала понять саму задачу. 

 smile 


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


Опытный
**


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

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



меня навели на мысль еще одного варианта решения, который, как мне кажется, является более изящным, чем первый:
Код

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#define MAXLINE        4096


class exFmt
{
 private:
  char _str[MAXLINE];

 public:
  const char *str()
   { return _str; }

  exFmt(const char *format, ...)
  {
   va_list    ap;
   va_start(ap, format);
   vsnprintf(_str, sizeof(_str), format, ap);
   va_end(ap);
  }

  exFmt(const exFmt &fmt)
   { memcpy(_str, fmt._str, sizeof(_str)); }

  exFmt() { }
};

class exBase
{
 private:
  exFmt        _fmt;

 public:
  const char *str()
   { return _fmt.str(); }

  exBase(const exFmt &fmt)
   { _fmt = fmt; }
};


class exDerived : public exBase
{
 public:
  exDerived(const exFmt &fmt) : exBase(fmt) { }
};


int main()
{
 try
 {
  throw exDerived(exFmt("the error occured in %d try-catch block", 1));
 }
 catch(exBase &ex)
 {
  printf("%s\n", ex.str());
 }

 return 0;
}



--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
Lazin
Дата 30.1.2010, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



этот вариант ни разу не изящный, обычный std::exception + boost.format - намного удобней, а главное обходятся без элипсиса smile 
PM MAIL Skype GTalk   Вверх
InvalidProperty
Дата 30.1.2010, 19:21 (ссылка)  | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

Это сообщение отредактировал(а) InvalidProperty - 30.1.2010, 19:22


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
Lazin
Дата 30.1.2010, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(InvalidProperty @  30.1.2010,  19:21 Найти цитируемый пост)
Lazin, удобство понятие относительное и сугубо индивидуальное
согласен, но ведь еще существуют объективные признаки кода с "душком", в данном случае это оно и есть smile 
я лично не понимаю, зачем все это, если можно просто отформатировать строку и передать ее в конструктор класса исключения, еще я не понимаю, почему не используется std::exception, а используется свой велосипед
ну и на последок, если я захочу получить тот или иной параметр не в текстовом виде, что мне делать?

Цитата(InvalidProperty @  30.1.2010,  19:21 Найти цитируемый пост)
Я, к примеру, недолюбливаю сторонние библиотеки, а строка форматирования printf для меня выглядит привычнее и удобнее.

лично я бы не хотел работать в одной команде с вело-строителем любителем, потому-что вместо того, что-бы просто писать код, придется изучать аналоги уже хорошо известных вещей, вроде boost::format и std::exception
вот к примеру вариант с boost::exception
(не ручаюсь за правильность, пишу по памяти)
Код

typedef boost::error_info<struct tag_line_number, std::string> LineNumberErrInfo;
typedef boost::error_info<struct tag_file_name, std::string> FileNameErrInfo;

class SpecificError : public boost::exception, public std::exception
{
};

....

try
{
...
   throw SpecificError() << LineNumberErrInfo(_LINE_) << FileNameErrInfo(__FILE__);
}
catch(SpecificError& e)
{
    std::cout << boost::diagnostics_information(e) << std::endl;
    std::cout << "Line: " << boost::get_error_info<LineNumberErrInfo>(e) << std::endl;
    ...
}

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

Это сообщение отредактировал(а) Lazin - 30.1.2010, 20:01
PM MAIL Skype GTalk   Вверх
Страницы: (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.0603 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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