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

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

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

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

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

class A
{
public: 
~A()
 {
  A a;
  ....
 }
 ....
};
. Деструктор класса вызывается при уничтожении любого его экземпляра, а в теле деструктора прописано безусловное создание, а значит и безусловное уничтожение ещё одного локального экземпляра того же класса. В результате бесконечная рекурсия.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

... *f(...)
{
...x;
...
return &x;
}
Нельзя возвращать указатели на автоматические локальные переменные, так как после возврата эти переменные не существуют.
... &f(...)
{
...x;
...
return &x;
}
И ссылки на такие переменные тоже возвращать нельзя. По той же причине.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

А здесь:
... &f(...)
{
static ... x;
....
return &x;
}
синтаксис локальной переменной использован не по назначению, что может сбивать с толку тех, кто не прочитает целиком тело функции. Если уж переменная фактически глобальна, то так её и объявите.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Оксалайя
Сообщения: 27
Зарегистрирован: 01 сен 2015, 12:12

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

Не объявляйте переменную глобальной, если вам нужна локальная.
Не объявляйте переменную локальной, если вам нужна глобальная.
Вообще не объявляйте переменную, если она вам не нужна...ту би континуед.
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

А ещё сколько этого же в учебниках по С++
[syntax=Delphi] [/syntax]
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Про локальный объект в конструкторе и деструкторе и про возврат ссылки на статическую локальную переменную мне ни где не попадалось.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Оксалайя
Сообщения: 27
Зарегистрирован: 01 сен 2015, 12:12

Сионист писал(а):Про локальный объект в конструкторе и деструкторе и про возврат ссылки на статическую локальную переменную мне ни где не попадалось.

А Вы ожидали где-нибудь увидеть что-то вроде "Не делайте бесконечную рекурсию, потому что получится бесконечная рекурсия"? Так для 99% людей это и так очевидно, Вы просто в эти 99% не попали :)
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Первый и второй вариант плюсую, хотя и не считаю указание таких вариантов особо полезными из-за их очевидности.

А вот третий вариант крайне спорен. Я неоднократно встречал функцию, возвращающую ссылку на локальную статическую переменную, которая делала какие-то дополнительные проверки перед возвратом. Если программист хочет, чтобы эти проверки выполнялись ВСЕГДА, когда внешний код хочет получить ссылку на общую переменную, то такой подход не только допустим, но и вообще является единственным возможным.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

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

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

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

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

private:
   // some private methods and fields

};
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Кто увидет и опишет суть проблемы
Очевидно, копирование будет нормально работать, если поля исходного класса не ссылочные. А если ссылочные, то новый класс и rhs будут содержать поля с одинаковыми ссылками. После уничтожения rhs поля нового класса будут указывать на участки памяти, которые более не доступны.
It's a long way to the top if you wanna rock'n'roll
Ответить