warning C4355
От: icWasya  
Дата: 12.02.13 11:22
Оценка:
Насколько опасен такой код
class B;
class classA{
public:
  classA(classB* bB):B(bB){;}
  operator int(void){return FB->value;}
private:
  classB* B;
};
class classB{
friend classA;

public:
  classA* A;
  classB():value(0),
       A(this)// <<==---- warning C4355
    {;} 

private:
  int value;
};

main()
{
  classB B;

  int value = B.A;
}
Re: warning C4355
От: Abyx Россия  
Дата: 12.02.13 11:26
Оценка: 4 (1)
Здравствуйте, icWasya, Вы писали:

описание предупреждения читали? что непонятно?
In Zen We Trust
Re: warning C4355
От: rg45 СССР  
Дата: 12.02.13 12:03
Оценка: +1
Здравствуйте, icWasya, Вы писали:


W>Насколько опасен такой код

  Использование this в списке инициализации
W>
W>class B;
W>class classA{
W>public:
W>  classA(classB* bB):B(bB){;}
W>  operator int(void){return FB->value;}
W>private:
W>  classB* B;
W>};
W>class classB{
W>friend classA;

W>public:
W>  classA* A;
W>  classB():value(0),
W>       A(this)// <<==---- warning C4355
W>    {;} 

W>private:
W>  int value;
W>};

W>main()
W>{
W>  classB B;

W>  int value = B.A;
W>}
W>


Цитата из MSDN:

The base-class constructors and class member constructors are called before this constructor. In effect, you've passed a pointer to an unconstructed object to another constructor. If those other constructors access any members or call member functions on this, the result will be undefined. You should not use the this pointer until all construction has completed.


Звучит это довольно странно, поскольку , согласно стандарту, сконструированным объект может считаться только после завершения работы конструктора (конструкторов всех уровней иерархии начледования). С этой точки зрения использование this в теле конструктора ни чем не лучше, чем в списке инициализации. Однако при использовании this в теле конструктора данное предупреждение не возникает. В целом, предупреждение достаточно бесполезное.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: warning C4355
От: B0FEE664  
Дата: 12.02.13 12:06
Оценка:
Здравствуйте, icWasya, Вы писали:

W>Насколько опасен такой код

Код очень опасен. Он вас "с головой" выдаёт. Имена classA, classB, переменная classB* bB много говорят об авторе... Да и в целом — код не компилируется.

Если же вы хотели спросить про warning C4355, то его можно игнорировать да тех пор пока в конструкторе classA::classA(classB* bB) не вызываются методы класса classB.

  Скрытый текст
W>
W>class B;//тут, видимо, должна была быть декларация class classB;, без которой этот код вообще не должен компилироваться.
W>class classA{
W>public:
W>  classA(classB* bB):B(bB){;}
W>  operator int(void){return FB->value;}//??? 
W>private:
W>  classB* B;
W>};
W>class classB{
W>friend classA;

W>public:
W>  classA* A;
W>  classB():value(0),
W>       A(this)// <<==---- warning C4355
W>    {;} 

W>private:
W>  int value;
W>};

W>main()
W>{
W>  classB B;

W>  int value = B.A;
W>}
W>
И каждый день — без права на ошибку...
Re: warning C4355
От: uzhas Ниоткуда  
Дата: 12.02.13 12:10
Оценка: 1 (1)
Здравствуйте, icWasya, Вы писали:

W>Насколько опасен такой код


именно в данном коде проблем не вижу, кроме того, что он не скомпилируется из-за FB->value
однако дополню:
1. мемберы класса инициализируются в порядке _объявления_, а не в порядке, указанном в списке инициализации
classB():value(0),
    A(this)


здесь сначала выставится A(this), а лишь потом value занулится, т.к. это соответствует порядку объявления мемберов класса classB

2. передавать this в списке инициализации куда-то _может быть иногда_ опасно (приводить к проблемам), т.к. его могут использовать еще до окончания работы конструктора. и тут могут быть сюрпризы на этапе выполнения. поэтому и выдается предупреждение, чтобы уберечь от подобных проблем

успехов
Re: warning C4355
От: icWasya  
Дата: 12.02.13 12:49
Оценка:
Действительно не компилируется — выдирал не проверяя
На самом деле классы шаблонные
  Вот это компилируется и даже наботает
template<class T>
class classB;

template<class T>
class classA{
public:
  classA(classB<T>* bB):B(bB){;}
  operator int (void){return B->value;}
private:
  classA(){;}
  classB<T>* B;
}; // Класс classA именно такой и в нём больше ничего нет

template<class T>
class classB{
friend classA<T>;
public:
  classA<T> A;
  classB():value(0),
       A(this)// <<==---- warning C4355
    {;}
public:
  /* тут другие методы*/
private:
  /* тут другие поля */
private:
  int value;
};
Re[2]: warning C4355
От: saf_e  
Дата: 13.02.13 12:36
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, icWasya, Вы писали:



W>>Насколько опасен такой код

R>
  Использование this в списке инициализации


R>Цитата из MSDN:

R>

R>The base-class constructors and class member constructors are called before this constructor. In effect, you've passed a pointer to an unconstructed object to another constructor. If those other constructors access any members or call member functions on this, the result will be undefined. You should not use the this pointer until all construction has completed.


R>Звучит это довольно странно, поскольку , согласно стандарту, сконструированным объект может считаться только после завершения работы конструктора (конструкторов всех уровней иерархии начледования). С этой точки зрения использование this в теле конструктора ни чем не лучше, чем в списке инициализации. Однако при использовании this в теле конструктора данное предупреждение не возникает. В целом, предупреждение достаточно бесполезное.


Тут не соглашусь, ибо в теле конструктора:

1. Гарантировано вызваны конструкторы родителей.
2. Гарантировано проинициализированы члены класса.

Т.е. объект валиден. Даже если не рассматривать множественное наследование, граблей можно все равно отгрести.
Re[3]: warning C4355
От: Jack128  
Дата: 13.02.13 18:39
Оценка: -1
Здравствуйте, saf_e, Вы писали:

_>Здравствуйте, rg45, Вы писали:


R>>Здравствуйте, icWasya, Вы писали:


_>2. Гарантировано проинициализированы члены класса.


не большой спец в плюсах, но насколько я знаю, при таком вызове контруктора my_class * p = new my_class; POD члены НЕ будут проинициализированы.

пруф: http://liveworkspace.org/code/3R4vvv$22
Re: warning C4355
От: __kot2  
Дата: 13.02.13 19:24
Оценка:
Здравствуйте, icWasya, Вы писали:
W>Насколько опасен такой код
в принципе, ничего смертельного
Re[4]: warning C4355
От: Abyx Россия  
Дата: 13.02.13 19:25
Оценка:
Здравствуйте, Jack128, Вы писали:

J>не большой спец в плюсах, но насколько я знаю, при таком вызове контруктора my_class * p = new my_class; POD члены НЕ будут проинициализированы.


и при чем тут это?
In Zen We Trust
Re[3]: warning C4355
От: rg45 СССР  
Дата: 13.02.13 20:42
Оценка:
Здравствуйте, saf_e, Вы писали:

R>>Звучит это довольно странно, поскольку , согласно стандарту, сконструированным объект может считаться только после завершения работы конструктора (конструкторов всех уровней иерархии начледования). С этой точки зрения использование this в теле конструктора ни чем не лучше, чем в списке инициализации. Однако при использовании this в теле конструктора данное предупреждение не возникает. В целом, предупреждение достаточно бесполезное.


_>Тут не соглашусь, ибо в теле конструктора:


_>1. Гарантировано вызваны конструкторы родителей.

_>2. Гарантировано проинициализированы члены класса.

_>Т.е. объект валиден...


Далеко не всегда. Время жизни объекта, согласно стандарту (п.3.8/1) начинается только после завершения его инициализации, т.о. говорить о валидности объекта во время работы конструктора не приходится. Конечно, это не значит что в конструкторе нельзя обращаться к членам, просто делать это нужно обдумано. При бездумном же отношении неприятности можно поиметь хоть в списке инициализации, хоть в теле конструктора. И список этих неприятностей не сводится к одному лишь неосторожному обращению с this — можно, например, нарваться на тот же pure virtual call.
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.