Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > наследование класса.вызов функции перед


Автор: DarkKnight 14.10.2008, 22:05
Доброго времени суток!
Допустим есть класс А и класс B.У класса Б не дефолтный конструктор,с чем справляюсь успешно,проблема в том,что при вызове конструктора(оператора new) наследующего класса нужно вызвать его конструткор,потом внутренюю приватную функцию,и потом только конструктор наследуемого класса.Т.е.:
1.вызываем конструктор класса А
2. вызываем функцию
3. вызываем конструткор класса Б

Код

class A: public B
{
      A(int gggg)
      : _abc(gggg) //та самая функция
      : B(gggg)
     {
          //null
      }
     ~A()
     {
          // null
      }
private:
      bool _abc(int a);
};


Нужно что-то типа этого.Такое вообще реально?

Автор: Daevaorn 14.10.2008, 22:18
Цитата(DarkKnight @  14.10.2008,  23:05 Найти цитируемый пост)
Такое вообще реально? 

так как вы описали нет.

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

Автор: J0ker 14.10.2008, 22:19
так сделать нельзя
конструкторы вызываются от предка к потомку
и в списке инициализации может быть только инициализация мемберов (ну и предков)

Добавлено через 1 минуту и 46 секунд
если вы точно опишите проблему - зачем это нужно - возможно мы сможем предложить вам более удобный дизайн - публичное наследование далеко не всегда правильное решение

Автор: DarkKnight 15.10.2008, 08:31
в общем суть проблемы:
1.нужно выделить пул в памяти
2.заполнить структуру с параметрами
3.вызвать конструктор класса B с передачей в него этой сруктуры.
Конкретнее - это инсталяция Хавока.
Мне нужно уместить все эти 3 действия в 1 функцию,желательно без передачи структуры в конструткор класса А(в нем и должна быть эта функция,а лучше - этой функцией должен быть его конструктор),при этом унаследовать все методы класса B.

Автор: maxim1000 15.10.2008, 11:35
ну так можно сделать статическую функцию, которая вернёт структуру для инициализаиции B:

Код

A(int ggg): B(func(qqq)) {}

Автор: DarkKnight 15.10.2008, 16:35
попробывал,эта функция даже не успевает вызваться(

Автор: DarkKnight 15.10.2008, 16:57
В общем я написал 2 класса - менеджер памяти и класс мира.
но если есть идеи по этой теме,буду раз прочитать и испробывать)

Автор: maxim1000 15.10.2008, 18:02
Цитата(DarkKnight @  15.10.2008,  16:35 Найти цитируемый пост)
попробывал,эта функция даже не успевает вызваться( 

а можно код привести?
а то уж очень странно, что функция не вызывается

Автор: DarkKnight 15.10.2008, 18:59
вызываться то она вызывается,но после вызова конструктора класса B,а нужно до. По сути так и должно быть,следуя логике кода - вызов функции из класса A.но т.к. конструктор класса А не вызван еще,она видимо игнорируется(функция),вызов конструктора класса B,вызов конструктора класса A.

код был такой(образно):
Код

class A : public B
{
public:
    A(int nn);
   ~A() 
      {
         // null
      };
protected:
     int _myfunc(int gg);
};

A::A(int nn) : B( _myfync(nn) )
{
     // null
}

int A::_myfunc(int gg)
{
     // тут у меня заполнялась структура и
     // стоял брэкпоинт, т.к. вылет
     // (который обычно происходит если не выделить блок памяти хавоку)
     // происходил до брэкпоинта,я решил что вызов функции
     // просто не происходил
     return gg;
}


Автор: maxim1000 15.10.2008, 21:11
Цитата(DarkKnight @  15.10.2008,  18:59 Найти цитируемый пост)
Код
class A : public B
{
public:
    A(int nn);
   ~A() 
      {
         // null
      };
protected:
     int _myfunc(int gg);
};

функция подготовки структуры должна быть статической, т.к. на момент вызова конструктора B объекта класса A ещё нету и вызов его нестатического метода - плохая идея

Цитата(DarkKnight @  15.10.2008,  18:59 Найти цитируемый пост)
     // тут у меня заполнялась структура и
     // стоял брэкпоинт, т.к. вылет
     // (который обычно происходит если не выделить блок памяти хавоку)
     // происходил до брэкпоинта,я решил что вызов функции
     // просто не происходил

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

Автор: DarkKnight 15.10.2008, 23:11
Цитата(maxim1000 @  15.10.2008,  21:11 Найти цитируемый пост)
для отладки я бы посоветовал использовать какие-нибудь более детерминированные события, чем вылет вывод на консоль, например, или MessageBox, если дело в Windows происходит

это хорошо конечно,но не в закрытом классе)а вылет именно в нем.а между конструкторами месажбокс я не умею ставить))


Цитата(maxim1000 @  15.10.2008,  21:11 Найти цитируемый пост)
функция подготовки структуры должна быть статической, т.к. на момент вызова конструктора B объекта класса A ещё нету и вызов его нестатического метода - плохая идея

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

З.Ы. я вроде нечайно кномпу репорт нажал,я не спецально,все ок)))

Автор: mes 16.10.2008, 00:02
Цитата(DarkKnight @  15.10.2008,  23:11 Найти цитируемый пост)

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

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

Автор: vinick 16.10.2008, 00:04
Цитата(DarkKnight @  15.10.2008,  23:11 Найти цитируемый пост)
если функция раньше пропускалась,то статическая не будет пропускаться?

Это программирование, а не гадание на картах. Тут ничего пропускаться не может. Я не знаю что говорит по этому поводу стандарт, но обычная логика и эксперимент, подсказывают что если в невиртуальном методе класса не вызывать других методов и не обращаться к полям класса, то этот метод можно вызывать до инициализации объекта. Но лучше не рисковать и сделать его все-таки статическим


Цитата(DarkKnight @  15.10.2008,  18:59 Найти цитируемый пост)
     // тут у меня заполнялась структура и
     // стоял брэкпоинт, т.к. вылет
     // (который обычно происходит если не выделить блок памяти хавоку)
     // происходил до брэкпоинта,я решил что вызов функции
     // просто не происходил

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

Автор: DarkKnight 16.10.2008, 09:07
Сейчас не поленился - переделал немного класс,функцию сделал статической,поставил cout в начале и конце функции и в конструкторе класса A,не вывелось ничего.

Автор: Daevaorn 16.10.2008, 09:30
DarkKnight
$ cat main.cpp 
Код

#include "iostream"

struct Base
{
    Base(int a)
    {
        std::cout << "Base = " << a << std::endl;
    }
};

struct Derived: public Base
{
    Derived(): Base(foobar(777))
    {
        std::cout << "Derived" << std::endl;
    }
protected:
        static int foobar(int a)
    {
        std::cout << "Foobar = " << a << std::endl;
                return a;
    }
};

int main()
{
    Derived d;
    return 0;
}


Код

$ g++ main.cpp  && ./a.out 
Foobar = 777
Base = 777
Derived

Автор: Lazin 16.10.2008, 09:57
я так понял, что функция, которую нужно вызвать до вызова конструктора, имеет отношение к менеджеру памяти
если это так, то стоит перегрузить операторы new - delete для объектов, использующих менеджер памяти

Код

class A: public B
{
    A(int gggg) : B()
    {
        //null
    }
    ~A()
    {
        // null
    }
    void* operator new (size_t sz)
    {
        //при вызове этой ф-ии конструктор объекта еще не вызван
        return malloc(sizeof(A));
    }
    void operator delete (void* p)
    {
        free(p);
    }
    void* operator new (size_t sz, std::nothrow)
    {
        //при вызове этой ф-ии конструктор объекта еще не вызван
        return malloc(sizeof(A));
    }
    void operator delete (void* p, std::nothrow)
    {
        free(p);
    }
    void* operator new[] (size_t sz)
    {
        //при вызове этой ф-ии конструктор объекта еще не вызван
        size_t obj_count = sz/sizeof(A);
        return malloc(sizeof(A)*obj_count);
    }
    void operator delete[] (void* p)
    {
        free(p);
    }
};

тут нужно вызовы malloc - free, заменить функциями своего менеджера памяти, и не забывать, что во время вызова new, объект еще не существует

Автор: DarkKnight 16.10.2008, 13:40
Код

#include "iostream"

struct Base
{
    Base(int a)
    {
        std::cout << "Base = " << a << std::endl;
    }
};

struct Derived: public Base
{
    Derived(): Base(foobar(777))
    {
        std::cout << "Derived" << std::endl;
    }
protected:
        static int foobar(int a)
    {
        std::cout << "Foobar = " << a << std::endl;
                return a;
    }
};

int main()
{
    Derived d;
    return 0;
}


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

Код


#ifndef HW_MAIN_H
#define HW_MAIN_H

namespace HavokWrapper
{

    class hwMemManager
    {
    public:
        hwMemManager();
        ~hwMemManager();
        void deAllocate(void);
    protected:
        hkPoolMemory* _memoryManager;
        hkThreadMemory* _threadMemory;
        char* _stackBuffer;

        /*
            Функция вывода ошибок
        */
        static void HK_CALL _errorReport(const char* msg, void*)
        {
            printf("%s", msg);
        }
    };

    hkpWorldCinfo _defaultWorldInfo;
    static hwMemManager* memMngr;

    class hwWorld : public hkpWorld
    {
    public:
        hwWorld(hkpWorldCinfo &winfo = _defaultWorldInfo);
        void releaseWorld(void);
        ~hwWorld();

        static hkpWorldCinfo _ppc_ml9(hkpWorldCinfo &na_nah)
        {
            std::cout << "zaebis" << std::endl;
            memMngr = HK_NULL;
            memMngr = new hwMemManager();
            return na_nah;
        }
    };
    

hwWorld::hwWorld(hkpWorldCinfo &winfo)
            : hkpWorld( _ppc_ml9(winfo) )
{
    std::cout << "zaebis" << std::endl;
}

hwWorld::~hwWorld()
{
    releaseWorld();
}

/*
    Полное уничтожение Мира
*/
void hwWorld::releaseWorld(void)
{
    markForWrite(); 
    removeReference();
}
    
};

#endif // HW_MAIN_H




скажи,люди добрые,что я сделал не так?

Автор: mes 16.10.2008, 14:08
Цитата(DarkKnight @  16.10.2008,  13:40 Найти цитируемый пост)

скажи,люди добрые,что я сделал не так?

а какой результат выполнения ? 

Автор: DarkKnight 16.10.2008, 14:15
Цитата(mes @  16.10.2008,  14:08 Найти цитируемый пост)
а какой результат выполнения ? 


результат выполнения - вылет,а в консоли пусто,кроме "Xors3D engine loaded!".

Автор: Daevaorn 16.10.2008, 14:17
DarkKnight, что за компилятор?

Добавлено через 26 секунд
И где весь код?

Автор: DarkKnight 16.10.2008, 14:19
компилятор MSVS 2008.
весь код у меня на винте)))а этого не достаточно?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)