Re[9]: Вызов конструктора (вдогонку)
От: Павел Кузнецов  
Дата: 30.12.02 07:49
Оценка:
Здравствуйте, __Nicolay, Вы писали:

ПК>>Будет undefined behavior, т.к. new (this) A в конструкторе A в конечном итоге приведет к тому, что к объекту типа A будет обращение через указатель типа B*. Указатель на "чужую" vmt — один из вариантов.


N>Не совсем понятно почему и где должен появится указатель на чужую vmt,


Не должен, а может :-)

N>я вижу только один способ достичь описанного результата


Наличие неопределенного поведения предполагает миллион таких способов.

ПК>>Например, следующая программа <...>


N>Приведенный вами код вылетает по причине переполнения стека, т.к. это просто бесконечная рекурсия


Семен Семеныч... :-)
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[10]: Вызов конструктора (вдогонку)
От: __Nicolay Россия  
Дата: 30.12.02 08:59
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Наличие неопределенного поведения предполагает миллион таких способов.


Я просто не до конца убежден что это undefined behavior. Это наверно следует из пунктов стандарта 3.8.5 — 3.8.7, только вот откуда конкретно, там слишком много хитрых терминов которыми я пока не владею (вроде нетривиальный конструктор/деструктор)?
Неопределено поведение только для классов с vmt или всегда?

Тогда код наподобие того что приведен в 3.8.7 для классов с виртуальными методами тоже приведет к undefined behavior?

N>>Приведенный вами код вылетает по причине переполнения стека, т.к. это просто бесконечная рекурсия


ПК>Семен Семеныч...

Я не прав?
... << RSDN@Home 1.0 beta 1 >>
Re: Вызов конструктора - от Микрософт :)
От: Vi2 Удмуртия http://www.adem.ru
Дата: 02.04.03 06:46
Оценка:
Здравствуйте, Atilla, Вы писали:

A>Корректен ли будет такой

A>A(int x, int y)
A>{
A>  A(x);
A>}

A>вызов конструктора из другого конструктора с точки зрения стандарта или нет?

Пример от Микрософт: ATLDBCLI.H — строка 1016

class CRowset
{
// Constructors and Destructors
public:
    CRowset()
    {
        m_pAccessor = NULL;
        m_hRow      = NULL;
    }
    CRowset(IRowset* pRowset)
    {
        m_spRowset  = pRowset;
        CRowset();
    }
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: Вызов конструктора (вдогонку)
От: Lorenzo_LAMAS  
Дата: 02.04.03 07:41
Оценка:
Павел, я конечно понимаю, что это старый топик, но раз уж он всплыл
Мне что-то твой пример совсем не понравился. Уж если писать, то так
class A{
public:
   A()
   {
      std::cout<<"A def ctor\n";
   }
   A(int)
   {
      this->A::~A();
      new(this)A;
   }
   virtual ~A()
   {
       std::cout<<"A dtor\n";
   }
};

class B:public A{
public:
   B():A(10)
   {}
   virtual ~B()
   {
      std::cout<<"B def ctor\n";
   }
};

int main()
{
    B * pB = new B;
    delete pB;

   return 0;
}


Но, хотя это и злостный undefined, все равно деструктор вызовется правильный и сработает все как и ожидалось, потому как ведь конструктор B все равно правильно установит vptr.

Так что пример неудачен.
Of course, the code must be complete enough to compile and link.
Re[9]: Вызов конструктора (вдогонку)
От: Павел Кузнецов  
Дата: 02.04.03 07:48
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

LL>Мне что-то твой пример совсем не понравился.


Мне тоже

LL>Так что пример неудачен.


Однозначно!
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: Вызов конструктора (вдогонку)
От: __Nicolay Россия  
Дата: 02.04.03 08:09
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

LL>Но, хотя это и злостный undefined, все равно деструктор вызовется правильный и сработает все как и ожидалось, потому как ведь конструктор B все равно правильно установит vptr.


Ну а если делать как в моем примере могут быть проблемы или нет?
Microsoft вообще вызываят конструкторы когда хочет, даже инициализирует константные члены заново например:

class _com_error {
public:
        _com_error(const _com_error& that) throw();

// ...

        _com_error& operator=(const _com_error& that) throw();

private:
        const HRESULT                   m_hresult;
        IErrorInfo *                    m_perrinfo;
        mutable TCHAR *                 m_pszMsg;
};

inline _com_error::_com_error(const _com_error& that) throw()
        : m_hresult(that.m_hresult), m_perrinfo(that.m_perrinfo), m_pszMsg(NULL)
{
        if (m_perrinfo != NULL) {
                m_perrinfo->AddRef();
        }
}

inline _com_error& _com_error::operator=(const _com_error& that) throw()
{
        if (this != &that) {
                this->_com_error::~_com_error();
                this->_com_error::_com_error(that);
        }
        return *this;
}



Можно ли переносимо сделать тоже самое, в данном случае оно конечно не надо, но в принципе интересно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.