Разбирал одну либу, столкнулся со следующим. Есть класс VDisk, в нем есть массив классов VFile (постоянное число). В конструкторе VDisk'а вызывается конструктор VFile'а для каждого элемента массива, но не через цикл, а с помощью передачи в некоторую функцию указателя на массив классов, размера одного элемента (класса), числа элементов (классов) и указателей на конструктор и деструктор VFile'а. Причем вызываемая функция была одмечена IDA как библиотечная. Как это осуществляется средствами языка?
Эээ... C++ знаешь? Код (Text): struct Shite { Shite() : m_something(0) { } int m_something; }; void func() { std::vector<Shite> v; v.resize(65); }
s0larian нет, а запостил отедльно от "начинающих в с/с+", т.к. побыстрее хотел получить ответ) Приведенный код не совсем то, что нужно. Но он навел меня на такой код, который приводит к нужному результату: Код (Text): class B { public: B () {}; }; class A { public: A() : b() { }; B b[N]; для инициализации b вызывается Код (Text): void __stdcall `vector constructor iterator'(void *,unsigned int,int,void * (__thiscall*)(void *)) Как сделать это внутри тела функции, хоть это вроде и не нужно, - не знаю. Так не компилируется: Код (Text): class A { public: A() {b();}; B b[N];
Это не скомпилится, т.к. нужна константа. Просто заполненный массив: Код (Text): void func() { Shite temp[16]; // stack Shite *temp2 = new Shite[16]; // heap }
Это в конструкторе, наверное, одно из первых действий? Так просто компилятор так код генерит. Вот, тот же эффект должен наблюдаться при дизассемблировании (осторожно с оптимизацией только): Код (Text): class A { public: int x; A() { x = 1; } B b[2000]; }; int main() { A a; // call `vector constructor iterator'(), a.x = 1. }
s0larian а) N - ессно константа. б) В последнем моем посте я имел в виду, что нельзя в теле функции-конструктора написать A() { b(); } а выше (не знаю как это называется) после круглых скобок через двоеточие можно: A() : b() {}, и это компилятор превратит в вызов функции отвечающей за вызов конструктора для каждого элемента массива. в) Shite *temp2 = new Shite[16]; // heap тоже, кстати, сводится к вызову 'vector constructor iterator', но здесь есть еще выделение памяти, в то время как в моем случае память уже была выделена. Sol_Ksacap а) да, это одно из первых действий. Первые два - инициализация стекового фрейма и установка обработчика исключений Но это и объясняется: A() : b() {}. б) В Вашем примере 'vector constructor iterator' не будет вызван, т.к. эта функция отвечает за инициализацию массива классов. Компилировал без оптимизации, все свелось к "a.x = 1;". P.S. а) Вроде бы старался в первом посте писать не двусмысленно. Откуда недопонимание? Надо было сразу приводить код, а в конце поставить знак "?". б) я плохо объясняю, тут лучше: http://members.ozemail.com.au/~geoffch@ozemail.com.au/samples/programming/msvc/language/compgen/
Возникла новая проблема - как вызвать деструктор для всех элементов массива используя 'vector destructor iterator', не в начале функции-деструктора? Но она быстро разрешилась: Код (Text): class B { public: B() {}; ~B() {}; }; class A { public: A() : b() {}; ~A() { b->~B();} B b[8]; }; int _tmain(int argc, _TCHAR* argv[]) { A a; }
Всё таки я склоняюсь к Placement New(конструирование с разделение фаз). Код (Text): #include <iostream> class Test { public: Test() { std::cout<<m_counter++<<std::endl; } void* operator new[] (size_t, void* p) { return p; } private: static int m_counter; }; int Test::m_counter = 0; int main() { const int countObj = 10; void *p= malloc(sizeof(Test)*countObj); Test *pTestArray = new (p) Test[countObj]; }
KeSqueer Надо было быть осторожнее с оптимизацией. Ещё осторожнее, ага. Код (Text): // main3.cpp // // cl main3.cpp kernel32.lib /Zi /link /entry:main // #include <windows.h> class B { public: B(){ CloseHandle((HANDLE)this); } }; class A { public: A(){ x = 1; } int x; B b[2000]; }; int main() { A a; } // http://img32.imageshack.us/img32/3198/sshot37.png Как видно по картинке, всё вызывается само в рамках конструктора. С деструктором то же самое – не нужно никаких ухищрений вроде A() : b() {}; или ~A() { b->~B();}.
Однако) Видимо при первом тесте забыл определить конструктор B в первом случае и деструктор - во втором, поэтому функции не вызывались. Спасибо, а то бы я продолжал использовать : b() и b->~B().
Ноу проблем Olly. Схему цветовую только сменили и подсветку кода отключили. Из-за, лайк, внезапного приступа паранойи.
Код (Text): class B { public: B() {}; ~B() {}; }; class A { public: A() : b() {}; ~A() { b->~B();} B b[8]; }; int _tmain(int argc, _TCHAR* argv[]) { A a; } все правильно токо b-> вызывать нинадо тоесть Код (Text): class B { public: B() {}; ~B() {}; }; class A { public: A() {}; ~A() {} B b[8]; }; int _tmain(int argc, _TCHAR* argv[]) { A a; }
скорее не библиотечная а встроеная для своих нужд компилятору точные параметры функции не пе помню и да их таких фунций бывает два вида первая используеться в конструкторах для создания массивов аргументы указатели на конструктор и деструктор класса и количество алементов ну и указатель на таблицу зис и что то еще- уже не помню и в деструторе для уничтожение тогоже массива все точно так же токо не передаеться адресс фунции конструктор класса