Страница 1 из 5

Как делать не надо

Добавлено: 05 ноя 2015, 12:16
Сионист

Код: Выделить всё

class A
{
 public:
  A ()
  {
   A a;
   ....
  }
 ....
};
Конструктор класса вызывается при создании любого экземпляра этого класса, а в теле конструктора прописано безусловное создание ещё одного локального экземпляра того же класса, для чего опять будет вызван тот же конструктор. Получается бесконечная рекурсия.

Код: Выделить всё

class A
{
public: 
~A()
 {
  A a;
  ....
 }
 ....
};
. Деструктор класса вызывается при уничтожении любого его экземпляра, а в теле деструктора прописано безусловное создание, а значит и безусловное уничтожение ещё одного локального экземпляра того же класса. В результате бесконечная рекурсия.

Re: Как делать не надо

Добавлено: 05 ноя 2015, 12:52
Сионист
... *f(...)
{
...x;
...
return &x;
}
Нельзя возвращать указатели на автоматические локальные переменные, так как после возврата эти переменные не существуют.
... &f(...)
{
...x;
...
return &x;
}
И ссылки на такие переменные тоже возвращать нельзя. По той же причине.

Re: Как делать не надо

Добавлено: 05 ноя 2015, 12:56
Сионист
А здесь:
... &f(...)
{
static ... x;
....
return &x;
}
синтаксис локальной переменной использован не по назначению, что может сбивать с толку тех, кто не прочитает целиком тело функции. Если уж переменная фактически глобальна, то так её и объявите.

Re: Как делать не надо

Добавлено: 05 ноя 2015, 13:56
Оксалайя
Ой, а дайте, дайте я добавлю таких же очевидных и общеизвестных советов :)

Не объявляйте переменную глобальной, если вам нужна локальная.
Не объявляйте переменную локальной, если вам нужна глобальная.
Вообще не объявляйте переменную, если она вам не нужна...ту би континуед.

Re: Как делать не надо

Добавлено: 05 ноя 2015, 14:13
Duncon
А ещё сколько этого же в учебниках по С++

Re: Как делать не надо

Добавлено: 05 ноя 2015, 14:30
Сионист
Про локальный объект в конструкторе и деструкторе и про возврат ссылки на статическую локальную переменную мне ни где не попадалось.

Re: Как делать не надо

Добавлено: 05 ноя 2015, 14:43
Оксалайя
Сионист писал(а):Про локальный объект в конструкторе и деструкторе и про возврат ссылки на статическую локальную переменную мне ни где не попадалось.

А Вы ожидали где-нибудь увидеть что-то вроде "Не делайте бесконечную рекурсию, потому что получится бесконечная рекурсия"? Так для 99% людей это и так очевидно, Вы просто в эти 99% не попали :)

Re: Как делать не надо

Добавлено: 05 ноя 2015, 14:51
Romeo
Первый и второй вариант плюсую, хотя и не считаю указание таких вариантов особо полезными из-за их очевидности.

А вот третий вариант крайне спорен. Я неоднократно встречал функцию, возвращающую ссылку на локальную статическую переменную, которая делала какие-то дополнительные проверки перед возвратом. Если программист хочет, чтобы эти проверки выполнялись ВСЕГДА, когда внешний код хочет получить ссылку на общую переменную, то такой подход не только допустим, но и вообще является единственным возможным.

Re: Как делать не надо

Добавлено: 05 ноя 2015, 14:53
Romeo
От меня чуть более сложная зарисовка, тоже про конструкторы. Лично встречал такой код в проекте. Кто увидит и опишет суть проблемы будет мною похвален:

Код: Выделить всё

classs CSomeClass
{
public:
   // default constructor
   CSomeClass() 
   {
      // some initialization code
   }

   // copy constructor
   CSomeClass(const CSomeClass rhs)
   {
      // some copy code
   }

private:
   // some private methods and fields

};

Re: Как делать не надо

Добавлено: 05 ноя 2015, 15:00
somewhere
Кто увидет и опишет суть проблемы
Очевидно, копирование будет нормально работать, если поля исходного класса не ссылочные. А если ссылочные, то новый класс и rhs будут содержать поля с одинаковыми ссылками. После уничтожения rhs поля нового класса будут указывать на участки памяти, которые более не доступны.