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

Зачем нужны конструктор и деструктор класса? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
YAUHEN
145 / 127 / 6
Регистрация: 29.07.2008
Сообщений: 506
27.09.2009, 01:13     Зачем нужны конструктор и деструктор класса? #1
вот задание:
Пользовательский класс Х должен содержать необходимые элементы-данные, которые создаются в динамической области памяти. Конструктор для их создания (операция new) и установки их начальных значений: Х (); деструктор: ~ Х (); friend – функция печати: friend void print(); функция, решающая поставленную задачу: friend Void Run(). Код методов и функций– вне пространства определения класса.

вот моя прога:
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
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <math.h>
#include "class.h"
 
class X
{
        double *x,*y,*z,res;
        friend void run();
        friend void print();
public:
    X(double=0, double=0, double=0);
    ~X();
};
 
X :: X(double x1, double y1, double z1)
    {//конструктор
        x=new double;
            x1=*x;
        y=new double;
            y1=*y;
        z=new double;
            z1=*z;
    }
 
void run(){
    res=(pow(y,x+1))/(pow(fabs(y-2),1.0/3)+3)+(x+y/2)/(2*fabs(x+y))*pow(x+1,(-1/sin(z)));
}
 
void print()
{
    std::cout<<"\nResult:"<<res;
}
 
X:: ~X() {};//деструктор
 
void main(void)
{
X(1.23,15.4,252.0);
run();
print();
getch();
}
я какбы толком не могу разобратся как работает конструктор и деструктор, и зачем они нужны, не моглибы на пальцах обьяснить?
и ещё компилятор выдаёт ошибку:
пишет что переменные res x y z undeclared identifier в строке
C++
1
res=(pow(y,x+1))/(pow(fabs(y-2),1.0/3)+3)+(x+y/2)/(2*fabs(x+y))*pow(x+1,(-1/sin(z)));
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.09.2009, 01:13     Зачем нужны конструктор и деструктор класса?
Посмотрите здесь:

C++ Создание класса с перегрузкой операторов конструктор и деструктор
C++ конструктор и деструктор
Конструктор инициализации, конструктор копирования, деструктор C++
Конструктор класса не видит конструктор по умолчанию другого класса C++
C++ При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
27.09.2009, 01:41     Зачем нужны конструктор и деструктор класса? #2
Ошибка "undeclared identifier" значит, что компилятор, по-русски говоря, не понимает, что это за переменные res, x, y да ещё и z
Неопознанные идентификаторы- вот как это переводится.
А оно на самом деле так.

Ибо хоть ты их объявил в классе, но они по умолчанию видимы ТОЛЬКО в пределах класса или при помощи специальных функций-членов (или методов) этого класса или так называемых дружественных функций (типа они дружат с классом и видят его всего.)

А ты просто решил к этим переменным обратиться, так не пойдёт.
...Вообще книжки читать надо. Там иногда полезные вещи пишут.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
27.09.2009, 02:14     Зачем нужны конструктор и деструктор класса? #3
вот так скомпилировалось:
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>
using std::cin;
using std::cout;
using std::endl;
 
#include <cmath>
 
class X {
private:
    double *x;
    double *y;
    double *z;
public:
    X(double x1, double y1, double z1);
    ~X();
    friend void printX(X obj);
    friend void runX(X obj);
};
 
X::X(double x1=0, double y1=0, double z1=0){
    x = new double(x1);
    y = new double(y1);
    z = new double(z1);
}
 
X::~X(){
    delete x;
    delete y;
    delete z;
}
 
void printX(X obj){
    cout << *(obj.x) << '\t' << *(obj.y) << '\t' << *(obj.z) << endl;
}
 
void runX(X obj){
    double x,y,z,res;
    x = *(obj.x);
    y = *(obj.y);
    z = *(obj.z);
    res=(pow(y,x+1.0))/(pow(fabs(y-2.0),1.0/3.0+3.0))+(x+y/2.0)/(2.0*fabs(x+y))*pow(x+1.0,(-1.0/sin(z)));
    cout << res << endl;
}
 
 
int main( void ){
    double a, b, c;
    cout << "Enter three double values for X: ";
    cin >> a >> b >> c;
    X o(a,b,c);
    cout << "Print X values:" << endl;
    printX(o);
    cout << "Calculate X values:" << endl;
    runX(o);
    return 0;
}
но вылетает на функции. Там изначально какой-то блудняк со скобками был. Как смог, переделал, но видимо неправильно. Мелкомягкий дебагер говорит, что
Код
Unhandled exception at 0x7c9109f9 in class_x.exe: 0xC0000005: Access violation reading location 0x00080181.
а скомпилённая gcc в cygwin вот так
Код
$ ./class_x.exe
Enter three double values for X: 44.4 -2.5 11.1
Print X values:
44.4    -2.5    11.1
Calculate X values:
inf
      5 [sig] class_x 3436 _cygtls::handle_exceptions: Error while dumping state
 (probably corrupted stack)
Segmentation fault (core dumped)
ругается...
При чём в cmd консоли что-то сосчиталось всё-таки
Код
Enter three double values for X: 2.2 1.21 22.1
Print X values:
2.2     1.21    22.1
Calculate X values:
18388.1
YAUHEN
145 / 127 / 6
Регистрация: 29.07.2008
Сообщений: 506
27.09.2009, 15:06  [ТС]     Зачем нужны конструктор и деструктор класса? #4
kravam, на сколько я понимаю что я написал в проге я и пытаюсь обратится к этим переменным через friend функцию.
easybudda с выражением проблем не должно быть тк в предыдущей лабе оно работало.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
27.09.2009, 15:22     Зачем нужны конструктор и деструктор класса? #5
YAUHEN, Да она у меня и без "выражения" вылетает. Кстати, самому интересно, с какого перепуга...
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
27.09.2009, 15:59     Зачем нужны конструктор и деструктор класса? #6
YAUHEN, прошу прощенья, не заметил.
Nick Alte
Эксперт С++
1561 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,896
Завершенные тесты: 1
27.09.2009, 20:36     Зачем нужны конструктор и деструктор класса? #7
Всё дело в передаче аргумента. Напиши в функциях не (X obj), а (X &obj), а ещё лучше (const X &obj).
Если интересна суть происходящего, то дело вот в чём - при передаче объекта в функцию срабатывает конструктор копирования. Поскольку он не объявлен явно, срабатывает созданная компилятором версия, поэлементно копирующая члены в новый объект. В нашем случае - указатели. При выходе из функции срабатывает деструктор аргумента и выделенная память (на которую ссылается как объект параметра, так и породивший его объект, живущий в функции main) уничтожается, после чего указатели объекта, сидящего в функции main начинают указывать "в никуда". Дальнейшее обращение по данным указателям и вызывает исключительную ситуацию.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
27.09.2009, 21:26     Зачем нужны конструктор и деструктор класса? #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>
using std::cin;
using std::cout;
using std::endl;
 
#include <cmath>
 
class X {
private:
    double *x;
    double *y;
    double *z;
public:
    X(double x1, double y1, double z1);
    ~X();
    friend void printX(const X &obj);
    friend void runX(const X &obj);
};
 
X::X(double x1=0, double y1=0, double z1=0){
    x = new double(x1);
    y = new double(y1);
    z = new double(z1);
}
 
X::~X(){
    delete x;
    delete y;
    delete z;
}
 
void printX(const X &obj){
    cout << *(obj.x) << '\t' << *(obj.y) << '\t' << *(obj.z) << endl;
}
 
void runX(const X &obj){
    double x,y,z,res;
    x = *(obj.x);
    y = *(obj.y);
    z = *(obj.z);
    res=(pow(y,x+1))/(pow(fabs(y-2),1.0/3)+3)+(x+y/2)/(2*fabs(x+y))*pow(x+1,(-1/sin(z))); // original
    cout << res << endl;
}
 
 
int main( void ){
    double a, b, c;
    cout << "Enter three double values for X: ";
    cin >> a >> b >> c;
    X o(a,b,c);
    cout << "Print X values:" << endl;
    printX(o);
    cout << "Calculate X values:" << endl;
    runX(o);
    return 0;
}
работает. При чём с оригинальной версией функции.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.03.2013, 13:34     Зачем нужны конструктор и деструктор класса?
Еще ссылки по теме:

Для класса задать конструктор и деструктор C++
C++ Конструктор и деструктор анонимного класса
C++ Нужно ли прописывать конструктор и деструктор для чисто виртуального абстрактного класса

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

Или воспользуйтесь поиском по форуму:
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
01.03.2013, 13:34     Зачем нужны конструктор и деструктор класса? #9
Цитата Сообщение от Nick Alte Посмотреть сообщение
При выходе из функции срабатывает деструктор аргумента и выделенная память (на которую ссылается как объект параметра, так и породивший его объект, живущий в функции main) уничтожается, после чего указатели объекта, сидящего в функции main начинают указывать "в никуда"
То есть я правильно понял- имеем объект ob с полями указателями, например (x,y,z) указывающими на определённую область памяти. Потом копируем этот объект, (не нарочно, а косвенно, вот так: (run (ob)), чего-то там делаем- проще говоря, делаем вычисления с разыменоваными указателями, а при возвращении из run указатели в x будут невалидны?

Да нет конечно. Замечу также, что деструктор, сработающий при выходе из run никакого влияния на память, на которую указывают указатели (я про x, y и z) не окажет- ибо его нет, этого деструктора.

А если мы его напишем:
C++
1
X:: ~X() {;delete x; delete y; delete z;};
Тогда да, по выходе из run(ob) указатели невалидны (что не значит, что вылетит исключение, у меня по ним мусор просто появляется.)

Тем не менее, конечно, правильно писать
C++
1
run (X& ob);
. Но это единственное на что будет влиять- на правильность данных, которые мы впоследствие будем выводит print. Но, повторюсь, в противном случае (а именно: run (X ob)) по выходе из run указатели в оригинальном объекте (а не в той копии, котрая была передана в run, как мы выяснили, она к этом времени исчезнет) всё равно останутся валидными.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Цитата Сообщение от easybudda Посмотреть сообщение
но вылетает на функции
на какой? У меня вот не вылетает нигде. Мусор есть, а вылетать не вылетает.
Yandex
Объявления
01.03.2013, 13:34     Зачем нужны конструктор и деструктор класса?
Ответ Создать тему
Опции темы

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