CPipedFactorialCalculator::CPipedFactorialCalculator(unsigned int x, const CBaseLog& logger)
: m_pipe ()
, m_initialValue(x)
, m_logger ( logger.createCopy() )
, m_pid ( ::fork() )
{
...
}
С++, список инициализатора
Суть проблемы, есть такой код:
Код:
Зачем считать факториал в отдельном потоке - потому, что того требует задание на лабу. То же и с пайпами.
Я думаю, вызов конструктора должен выполнятся следующим образом:
1. создается объект m_pipe,
2. создается объект m_initialValue
3. создается объект m_logger
4. создается объект m_pid - в этот момент происходит "раздвоение на два процесса"
5. создаются остальные члены класса, не указанные в списке инициализатора.
На самом же деле сначала "раздваивается на два процесса", и лишь затем обрабатывается список инициализатора.
Решение-то конечно простейшее, fork вынести в тело конструктора, но все же не приятно... Скажите, пожалуйста, кто ошибается, я или компилятор? :)
Объявление класса в студию.
Код:
class CBaseLog;
class CPipedFactorialCalculator // управляет взаимодействием процессов
{
typedef auto_ptr<CBaseLog> TLoggerPtr;
public:
CPipedFactorialCalculator (unsigned int x, const CBaseLog& logger);
~CPipedFactorialCalculator();
double getResult();
bool setResult(double result);
private:
pid_t m_pid;
CPipe m_pipe;
unsigned int m_initialValue;
TLoggerPtr m_logger;
bool isChild () {return m_pid == 0;}
bool isValid () {return m_pid !=-1;}
bool calculate ();
};
class CPipedFactorialCalculator // управляет взаимодействием процессов
{
typedef auto_ptr<CBaseLog> TLoggerPtr;
public:
CPipedFactorialCalculator (unsigned int x, const CBaseLog& logger);
~CPipedFactorialCalculator();
double getResult();
bool setResult(double result);
private:
pid_t m_pid;
CPipe m_pipe;
unsigned int m_initialValue;
TLoggerPtr m_logger;
bool isChild () {return m_pid == 0;}
bool isValid () {return m_pid !=-1;}
bool calculate ();
};
PS: Таков стандарт.
ЗЫ. По умолчанию этот варнинг отключен...
С этой опцией действительно выдает следующее:
Код:
child.h: In constructor ‘CPipedFactorialCalculator::CPipedFactorialCalculator(unsigned int, const CBaseLog&)’:
child.h:29: предупреждение: ‘CPipedFactorialCalculator::m_pipe’ будет инициализирован после
child.h:28: предупреждение: ‘pid_t CPipedFactorialCalculator::m_pid’
child.cpp:14: предупреждение: when initialized here
child.h:29: предупреждение: ‘CPipedFactorialCalculator::m_pipe’ будет инициализирован после
child.h:28: предупреждение: ‘pid_t CPipedFactorialCalculator::m_pid’
child.cpp:14: предупреждение: when initialized here
Значения функций, возвращаемых в список инициализации, вычисляются до начала инициализации элементов т.е. вызов m_pidfork расладывается на pid_t __temp_pid = fork; m_pid__temp_pid;. Чтобы все работало так как вы хотите, надо использовать язык подерживающий lazy evaluations.
Цитата: Serebrjany mir
Значения функций, возвращаемых в список инициализации, вычисляются до начала инициализации элементов
Покажи пункт стандарта это регламентирующий.
Практика показывает иное:
Код:
#include <iostream>
using namespace std;
struct A
{
A(int val)
{
cout << "A(int)" << endl;
}
};
int func()
{
cout << "func()" << endl;
return 1;
}
struct B
{
A a1, a2;
B() :a1(func()), a2(func())
{
cout << "B()" << endl;
}
};
int main()
{
B b;
return 0;
}
using namespace std;
struct A
{
A(int val)
{
cout << "A(int)" << endl;
}
};
int func()
{
cout << "func()" << endl;
return 1;
}
struct B
{
A a1, a2;
B() :a1(func()), a2(func())
{
cout << "B()" << endl;
}
};
int main()
{
B b;
return 0;
}
Вывод:
Цитата:
func()
A(int)
func()
A(int)
B()
Цитата: Serebrjany mir
Чтобы все работало так как вы хотите, надо использовать язык подерживающий lazy evaluations.
Зачем?
Кстати, отложенные вычисления эмулируются и C++.
Цитата: Serebrjany mir
Значения функций, возвращаемых в список инициализации, вычисляются до начала инициализации элементов т.е. вызов m_pidfork расладывается на pid_t __temp_pid = fork; m_pid__temp_pid;. Чтобы все работало так как вы хотите, надо использовать язык подерживающий lazy evaluations.
ISO/IEC 14882
Цитата:
12.6.2 Initializing bases and members
...
There is a sequence point (1.9) after the initialization of each base and member. The expression-list of a mem-initializer is evaluated as part of the initialization of the corresponding base or member.
...
Поцаны. Вам не кажется что это - бот?!
Цитата: Phodopus
Поцаны. Вам не кажется что это - бот?!
Точняк...
Забанен!
Ппц.. Я с самого момента его появления раза 3 жаловался точно. А это уже давно было! А вы с ним разговоры затеваете :D