Как правильно распределить память в конструкторе C ++? - PullRequest
6 голосов
/ 12 августа 2010

Какой правильный способ выделить память через new в конструкторе C ++. Первый путь в списке аргументов:

class Boda {
    int *memory;
    public:
        Boda(int length) : memory(new int [length]) {}
        ~Boda() { delete [] memory; }
};

или в теле конструктора:

class Boda {
    int *memory;
    public:
        Boda(int length) {
            memory = new int [length];
        }
        ~Boda() { delete [] memory; }
};

Спасибо, Бода Цидо.

Ответы [ 6 ]

3 голосов
/ 12 августа 2010

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

Итак:

class Boda {
    boost::scoped_array<int> memory;
    public:
        Boda(int length) : memory(new int [length]) {}
       ~Boda() {}
};

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

2 голосов
/ 12 августа 2010

Вы должны использовать классы управления ресурсами, которые будут обрабатывать это для вас. Иначе вы столкнетесь с некоторыми серьезными проблемами с безопасностью исключений, за исключением ненужного дублирования существующей логики и обслуживания операторов копирования / назначения.

2 голосов
/ 12 августа 2010
1 голос
/ 12 августа 2010

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

0 голосов
/ 12 августа 2010

memory переменная-член является указателем, если вы выделите ее в списке инициализации и она не будет выполнена, ваш класс не будет инициализирован и вам не нужно будет его освобождать позже (благодаря шаблону разработки RAIIкоторый используется C ++ для инициализации класса).Если вы выделите его память внутри тела конструктора, произойдет похожее поведение.

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

0 голосов
/ 12 августа 2010

Если вы хотите отлавливать ошибки выделения памяти (что вам, вероятно, следует), то вам придется выполнить вызов new в теле конструктора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...