Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Статическая инициализация структур

284
21 ноября 2005 года
michael_is_98
587 / / 25.02.2005
Скажите пожалуйста, можно ли статически проинициализировать следующие структуры:
Код:
struct ZRVParam
{
char *s;
double d;
};

struct ZRV
{
int nomer;
char *naim;
int nparam;
ZRVParam *param;
double (*func)(...);
};

Первую структуру - возможно. Например,
 
Код:
ZRVParam NormParam[] =  {
    {"среднее",0.0},             {"стандартное отклонение",1.0}
            }

Но вот вторая - вопрос. Она должна включать указатель на переменную или массив типа ZRVParam и указатель на функцию.
Функции написаны, но проинициализировать вторую структуру не удается.
3
21 ноября 2005 года
Green
4.8K / / 20.01.2000
У меня всё инициализируется:
Код:
struct ZRVParam
{
  char *s;
  double d;
};

struct ZRV
{
  int nomer;
  char *naim;
  int nparam;
  ZRVParam *param;
  double (*func)(...);
};

double func0(...) { return 0; }
double func1(...) { return 0; }

ZRVParam NormParam[] ={
  {"среднее",0.0},
  {"стандартное отклонение",1.0}
};

ZRV zrv[] = {
  {0, "0", 0, NormParam, func0},
  {1, "1", 1, NormParam, func1}
};

А вообще, код некрасивый...
284
22 ноября 2005 года
michael_is_98
587 / / 25.02.2005
Цитата:
Originally posted by Green
У меня всё инициализируется:
Код:
struct ZRVParam
{
  char *s;
  double d;
};

struct ZRV
{
  int nomer;
  char *naim;
  int nparam;
  ZRVParam *param;
  double (*func)(...);
};

double func0(...) { return 0; }
double func1(...) { return 0; }

ZRVParam NormParam[] ={
  {"среднее",0.0},
  {"стандартное отклонение",1.0}
};

ZRV zrv[] = {
  {0, "0", 0, NormParam, func0},
  {1, "1", 1, NormParam, func1}
};

А вообще, код некрасивый...


Как будет красивее?

3
22 ноября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by michael_is_98
Как будет красивее?


Гы.. А вот не знаю...
(что-то вопрос в тупик поставил)
Всё зависит от цели.
Для начала я бы сделал не структуры, а классы, и инициализировал через конструкторы. Это было бы очевиднее.
Потом убрал бы использование функция с троеточием, сделал бы функции с конкретным набором параметров, возможно шаблонные. Возможно, что это будут и не функции, а функторы.

А ZRV обязательно должен ссылаться на ZRVParam?
Он не может просто агрегировать эту структуру?

Ну в общем дальше сложно сказать. Просто, такая статическая инициализации выглядит ужасающе. И мне кажется, может привести к неявным ошибкам.
Может есть смысл создать класс-контейнер для всех ZRV, и в его конструкторе все инициализировать?

284
23 ноября 2005 года
michael_is_98
587 / / 25.02.2005
Цитата:
Originally posted by Green
Гы.. А вот не знаю...
(что-то вопрос в тупик поставил)
Всё зависит от цели.
Для начала я бы сделал не структуры, а классы, и инициализировал через конструкторы. Это было бы очевиднее.
Потом убрал бы использование функция с троеточием, сделал бы функции с конкретным набором параметров, возможно шаблонные. Возможно, что это будут и не функции, а функторы.

А ZRV обязательно должен ссылаться на ZRVParam?
Он не может просто агрегировать эту структуру?

Ну в общем дальше сложно сказать. Просто, такая статическая инициализации выглядит ужасающе. И мне кажется, может привести к неявным ошибкам.
Может есть смысл создать класс-контейнер для всех ZRV, и в его конструкторе все инициализировать?


Там на самом деле все просто. Есть набор функций - они генерируют случайную величину, подчиненную определенному закону распределения вероятностей (ЗРВ) (например, нормальный, Пуассона). Все эти функции возвращают вещественное число типа double. Набор параметров для различных ЗРВ свой. Например, чтобы сгенерировать нормальную случ.величину, нужно задать два вещ. параметра (среднее, станд.отклонение), чтобы сгенерировать случ.величину Пуассона - один параметр (лямбда).
Все эти функции есть, известно число передаваемых параметров, их названия, просто для удобства я попытался записать это в одну структуру.
В структуру ZRVParam - название параметра и его значение, в струткуру ZRV - название генерируемого ЗРВ (naim), число параметров (nparam), указатель на структуру ZRVParam с числом элементов nparam, и указатель на функцию генерирующую данный ЗРВ. Вот например, как это выглядит для нормального ЗРВ и ЗРВ Пуассона

 
Код:
const ZRVParam Param1[] =   {
                    {"среднее",0.0},
                    {"стандартное отклонение",1.0}
                };
const ZRVParam Param2[] = {{"лямбда",0}};

const ZRV zrv[]=    {
                {1,"Нормальное",sizeof(Param1)/sizeof(Param1[0]),Param1,(double (*)(...))MGAUSS},
                {2,"Пуассона",sizeof(Param2)/sizeof(Param2[0]),Param2,(double (*)(...))MPUAS}
            };

Функции MGAUSS, MPUAS описаны так
 
Код:
//    S,ДEЙCTBИTEЛЬHЫЙ,CPEДHEE                        
//   SIG,ДEЙCTBИTEЛЬHЫЙ,>0,CTAHДAPTHOE OTKЛOHEHИE
double MGAUSS(double s, double sig);
// p - параметр "лямбда"
double MPUAS(double p)
3
28 ноября 2005 года
Green
4.8K / / 20.01.2000
Может, тогда есть смысл создать интерфейс, который будет предоставлять общие методы: получение случайного значения, получение названия ЗВР, ну и если надо список параметров.
Например:
 
Код:
class ZVR
{
public:
  virtual ~ZVR() {}

  double         getRndValue() = 0;
  const char*    getName()     = 0;
  list<ZRVParam> getParams()   = 0;
};

А далее для каждого закона распределения отнаследовать свой класс:
Код:
class NormalZVR :public ZVR
{
public:
  NormalZVR(double standardDeviation, double average)
    : standardDeviation(standardDeviation),
      average(average) {}
  virtual ~NormalZVR() {}

  double         getRndValue() { return double MGAUSS(average, standardDeviation); }
  const char*    getName()     { return "Нормальное"; }
  list<ZRVParam> getParams()   {
    list<ZRVParam> params;
    params.push_back( ZRVParam("стандартное отклонение", standardDeviation) );
    params.push_back( ZRVParam("среднее", average) );
    return params;
  }

private:
  double standardDeviation;
  double average;  
};


class PoissonZVR :public ZVR
{
public:
  PoissonZVR(double lambda) :lambda(lambda) {}
  virtual ~PoissonZVR() {}

  double         getRndValue() { return MPUAS(lambda); }
  const char*    getName()     { return "Пуассона"; }
  list<ZRVParam> getParams()   {
    list<ZRVParam> params;
    params.push_back( ZRVParam("лямбда", lambda) );
    return params;
  }

private:
  double lambda;  
};

Конечно, коллекции параметров можно возвращать и др. способами, list я привел, как пример.

Если надо объявлять статический массив различных законов с различными параметрами, то можно добавить для удобства ещё один класс (умный указатель):
Код:
class PtrZVR
{
public:
    template<class T>
    PtrZVR(T& ref) :ptr(new T(ref)) {}
    ~PtrZVR()                       { delete ptr;}
    ZVR& operator*() const          { return (*ptr); }
    ZVR* operator->() const         { return (&**this); }

private:
    ZVR* const ptr;
};

Теперь можно создавать статические массивы:
 
Код:
const PtrZVR zrv[]= { NormalZVR(1.0,0.0), PoissonZVR(0.0) };


А так можно вывести названия законов и результаты:
 
Код:
int main()
{
    for(int i=0; i<sizeof(zrv)/sizeof(zrv[0]); ++i) {
        std::cout << zrv->getName() << " : " << zrv->getRndValue() << std::endl;
    }

    return 0;
}
284
09 декабря 2005 года
michael_is_98
587 / / 25.02.2005
Почему в определениии класса ZRV обязательно пишется
double getRndValue() = 0;
Компилятор ругается. Если написать
virtual double getRndValue() = 0;
то все нормально, но зачем писать =0;?

Зачем нужен "умный укзатель"?
398
09 декабря 2005 года
Alexandoros
630 / / 21.10.2005
если написать virtual void func() = 0; то для даной ф-ции ненужно создавать тело. А так же компилятор не даст создать екземпляр даного класа, только от производных.

Смарт поинтеры нужны для предотвращения ликимемори. Он автоматом уничтожается при выходе из блока в котором он объявлен.
В принципе в Студии есть уже клас смартпоинтера - auto_ptr.
3
09 декабря 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by michael_is_98
Почему в определениии класса ZRV обязательно пишется
double getRndValue() = 0;
Компилятор ругается. Если написать
virtual double getRndValue() = 0;
то все нормально, но зачем писать =0;?


Ссори, я очепятался. Конечно, нужно написать вначале virtual.
ZVR - это интерфейс, т.е. чисто абстрактный класс, который определяет лишь интерфейс наследников, но не имеет реализации. Поэтому и virtual double getRndValue() = 0;

Цитата:
Originally posted by Alexandoros

Смарт поинтеры нужны для предотвращения ликимемори. Он автоматом уничтожается при выходе из блока в котором он объявлен.
В принципе в Студии есть уже клас смартпоинтера - auto_ptr.


Автоматическое уничтожение объектов - это лишь одна из функций умных указателей.
А вообще умные указатели - это классы расширяющие функциональность обычных указателей. Т.е. внешне они выглядят, как указатели, но на самом деле совершают некоторые полезные действия с объектами, на которые ссылаются.
В моём примере умный указатель позволяет скопировать объект. Без него тебе бы пришлось сначала создать глобальные объекты, а потом занести указатели на них в массив:

 
Код:
const static NormalZVR normalZVR(1.0,0.0);
const static PoissonZVR(0.0) poissonZVR(0.0);

ZVR* const zrv[]= { (ZVR*)&normalZVR, (ZVR*)&poissonZVR };

С умным же указателем все очевиднее и приятнее на вид:
 
Код:
const PtrZVR zrv[]= { NormalZVR(1.0,0.0), PoissonZVR(0.0) };
284
12 декабря 2005 года
michael_is_98
587 / / 25.02.2005
А есть какая-либо литература по "умным указателям" и новым технологиям программирования. В Подбельском не встречал подобного. Может быть, это у Буча есть?
2.4K
12 декабря 2005 года
dinasok51
219 / / 12.11.2005
Цитата:
Originally posted by michael_is_98
А есть какая-либо литература по "умным указателям" и новым технологиям программирования. В Подбельском не встречал подобного. Может быть, это у Буча есть?



Про Smart-указатели здесь
или здесь

284
13 декабря 2005 года
michael_is_98
587 / / 25.02.2005
Цитата:
Originally posted by dinasok51
Про Smart-указатели здесь
или здесь


Эти книги одно и то же?

2.4K
13 декабря 2005 года
dinasok51
219 / / 12.11.2005
Цитата:
Originally posted by michael_is_98
Эти книги одно и то же?


Да.
По второй ссылке у меня быстрее скачалась.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог