Форум программистов, компьютерный форум CyberForum.ru

new и delete - C++

Восстановить пароль Регистрация
 
bgm123
39 / 39 / 16
Регистрация: 29.01.2013
Сообщений: 277
15.07.2013, 14:40     new и delete #1
Ошибка, незнаю как для моего класса выделить память. Как исправить?


C++
1
2
3
4
5
6
7
8
9
class MyClass {
int a, b, c;
public:
MyClass(int a, int b, int c)
}
 
void main(){
  MyClass *ptr = new MyClass[10];
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2013, 14:40     new и delete
Посмотрите здесь:

"delete [] a, b;" эквивалентно "delete [] a; delete [] b;"? C++
C++ delete[]
new - delete C++
C++ delete this
C++ delete[]
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
15.07.2013, 14:42     new и delete #2
C++
1
MyClass *ptr = new MyClass( 1, 2, 3 );
Только у тебя в описании класса ошибка, не хватает тела цикла конструктора.
SatanaXIII
Супер-модератор
Эксперт С++
 Аватар для SatanaXIII
5549 / 2563 / 233
Регистрация: 01.11.2011
Сообщений: 6,334
Завершенные тесты: 1
15.07.2013, 14:43     new и delete #3
C++
1
2
3
4
5
6
7
8
9
10
11
12
class MyClass {
int a, b, c;
public:
MyClass(int _a, int _b, int _c)
  {a=_a; b=_b; c=_c;}
};
 
void main(){
  MyClass *ptr[10];
  for(int i=0; i<10; i++)
    ptr[i] = new MyClass(i, i, 10);
}
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
15.07.2013, 14:46     new и delete #4
Цитата Сообщение от SatanaXIII Посмотреть сообщение
{a=_a; b=_b; c=_c;}
но зачем, если есть список инициализации?
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
15.07.2013, 14:50     new и delete #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass 
{
private:
    int a, b, c;
public:
    MyClass(): a(0), b(0), c(0)
    {}
    MyClass(int aGet, int bGet, int cGet): a(aGet), b(bGet), c(cGet)
    {}
};
 
int main() 
{
 
    MyClass *ptr = new MyClass[10];
 
    return 0;
}
*Конструктор по умолчанию не обязателен.
**Если я не ошибаюсь поля класса по умолчанию private
SatanaXIII
Супер-модератор
Эксперт С++
 Аватар для SatanaXIII
5549 / 2563 / 233
Регистрация: 01.11.2011
Сообщений: 6,334
Завершенные тесты: 1
15.07.2013, 14:53     new и delete #6
Цитата Сообщение от alex_x_x Посмотреть сообщение
но зачем, если есть список инициализации?
Ибо нагляднее.
C++
1
2
3
MyClass(int _a, int _b, int _c)
:a(_a), b(_b), c(_c)
{}
Добавлено через 23 секунды
Цитата Сообщение от Ilot Посмотреть сообщение
**Если я не ошибаюсь поля класса по умолчанию private
Так и есть.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
15.07.2013, 15:18     new и delete #7
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Ибо нагляднее.
C++
1
MyClass(int a, int b, int c) :a(a), b(b), c(c) {}
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
15.07.2013, 16:43     new и delete #8
А чтобы можно было создавать массивы (судя по всему ТС это нужно), имеет смысл задать параметры по умолчанию и объявить конструктор явным:
C++
1
explicit MyClass(int a=0, int b=0, int c=0) :a(a), b(b), c(c) {}
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
15.07.2013, 16:46     new и delete #9
А так что мешает?
C++
1
2
MyClass() :a(0), b(0), c(0) {}
MyClass(int a, int b, int c) :a(a), b(b), c(c) {}
Необходимость в параметрах по-умолчанию может быть вовсе ни к чему.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
15.07.2013, 16:56     new и delete #10
Цитата Сообщение от lazybiz Посмотреть сообщение
А так что мешает?
Ничто не мешает. Выбирайте вариант, который будет предпочтительнее для конкретной задачи.
Если вызовы конструктора с одним или двумя аргументами не приемлемы, то можно использовать Ваш вариант. Хотя я бы сделал несколько иначе (C++11):
C++
1
2
MyClass() :MyClass( 0, 0, 0) {}
MyClass(int a, int b, int c) :a(a), b(b), c(c) {}
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
15.07.2013, 17:10     new и delete #11
Ну вот к конструкции с делегирующими конструкторами надо как раз подходить очень и очень осторожно. Потому что если объемлющий конструктор выбросит исключение, мы попали :-(
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
15.07.2013, 17:22     new и delete #12
Цитата Сообщение от CheshireCat Посмотреть сообщение
Потому что если объемлющий конструктор выбросит исключение, мы попали :-(
В каком смысле "попали"? Объект ведь не будет считаться сконструированным, пока самый внешний конструктор успешно не завершиться.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
15.07.2013, 17:31     new и delete #13
Нет. Он будет считаться "сконструированным" (и для него будет вызван деструктор!), как только завершится первый конструктор. Вот пример кода: (компиль GCC 4.8)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <stdexcept>
using namespace std;
 
class Simple
{
    int value;
 
public:
    Simple(): value(0) { cout << "Simple default ctor" << endl; }
    Simple(int i): value(0) { cout << "Simple(int) ctor" << endl; throw runtime_error("some shit"); }
    ~Simple() { cout << "Simple dtor" << endl; }
};
 
class Test
{
    int value;
 
public:
    Test(): value(0) { cout << "Test default ctor" << endl; }
    Test(int i): Test() { cout << "Test(int) ctor" << endl; throw runtime_error("oooops!!!"); }
    ~Test() { cout << "Test dtor" << endl; }
};
 
int main()
{
    try
    {
        {
            Simple();
        }
        {
            Simple(1);
        }
    }
    catch(exception& ex)
    {
        cout << ex.what() << endl;
    }
    cout << endl;
 
    try
    {
        {
            Test();
        }
        {
            Test(1);
        }
    }
    catch(exception& ex)
    {
        cout << ex.what() << endl;
    }
    return 0;
}
Вывод:
Simple default ctor
Simple dtor
Simple(int) ctor
some shit

Test default ctor
Test dtor
Test default ctor
Test(int) ctor
Test dtor
oooops!!!
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
15.07.2013, 17:45     new и delete #14
CheshireCat, хотя, логика в этом есть. Если первый конструктор завершился, то объект создан. Остальные действия (внешний конструктор) должны обеспечивать более "специфическую" настройку полноценного созданного объекта. Но мне пока всё-таки не очень ясна суть "попадания", которое Вы упомянули.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
15.07.2013, 17:55     new и delete #15
Да, логика есть, я согласен. А суть "попадалова" в том, что деструктор может совершить действия, к которым "недоделанный" объект еще не готов, и которые не были предусмотрены программистом, - например, если в деструкторе закрывается соединение с базой данных, а открывается оно - только в объемлющем конструкторе. И, например, управляющие поля в момент вызова деструктора еще содержат "мусор". Да мало ли что еще...

Вывод из этого эксперимента такой: первый же конструктор должен оставить объект в полностью валидном состоянии, не полагаясь на возможные последующие вызовы других конструкторов для "достройки" объекта. Чтобы деструктор не "уронил" случайно недостроенный объект, а с ним - и всю программу. Вот об этом программист должен помнить постоянно.

Именно поэтому подходить к делегированию конструкторов нужно очень осторожно и вдумчиво.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
15.07.2013, 18:12     new и delete #16
Цитата Сообщение от CheshireCat Посмотреть сообщение
первый же конструктор должен оставить объект в полностью валидном состоянии
Но ведь и без делегирования каждый конструктор должен создавать полноценный объект, не требующий "достраивания". А если и есть некоторое "достраивание", то деструктор в любом случае должен делать очистку, опираясь на всё множество конструкторов (ведь объект может быть создан любым конструктором), а не на какой-то один из них. Иначе уже косяк будет.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
15.07.2013, 20:10     new и delete #17
Цитата Сообщение от Tulosba Посмотреть сообщение
Но ведь и без делегирования каждый конструктор должен создавать полноценный объект, не требующий "достраивания".
Думаю, может быть такая ситуация: написал один приватный конструктор с общей логикой, который лишь частично инициализирует объект и которому все остальные делегируют... бум
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
15.07.2013, 20:27     new и delete #18
Цитата Сообщение от Tulosba Посмотреть сообщение
деструктор в любом случае должен делать очистку, опираясь на всё множество конструкторов (ведь объект может быть создан любым конструктором), а не на какой-то один из них. Иначе уже косяк будет.
Да будет! Но ИМХО это проблема не столько множества конструкторов, сколько логичного разбиения на классы. Т.е. каждый класс должен выполнять только одну задачу и его деструктор не должен гадать, какую из задач зачистить.
Если не понятно, то вспомню один увиденный здесь на форуме пример "класса строки"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyStr{
private:
  std::string A;
  char* B;
public:
//2 разных конструктора инициализируют ЛИБО А ЛИБО B
//причём один из них по-умолчанию
  MyStr():A("Hello"){};//B =???
  MyStr(char* arg){
     B=new char[strlen(arg)+1];
     strcpy(B, arg);
  }
  ~MyStr(){delete[] B;}//Если объект создан констр-м по-умолчалию, то ошибка!
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.07.2013, 21:12     new и delete
Еще ссылки по теме:

delete[] *pointer vs. delete pointer и утечка памяти C++
New/Delete C++
New delete C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
15.07.2013, 21:12     new и delete #19
Kuzia domovenok, может у меня не очень получилось донести мысль, но говорил я примерно о том же. Деструктор должен правильно уничтожать объект вне зависимости от того, каким конструктором он создан. А пример со строковым классом просто напросто содержит логическую ошибку, т.к. не инициализирует освобождаемое поле.
Yandex
Объявления
15.07.2013, 21:12     new и delete
Ответ Создать тему
Опции темы

Текущее время: 00:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru