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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
YAUHEN
146 / 128 / 6
Регистрация: 29.07.2008
Сообщений: 506
#1

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

27.09.2009, 01:13. Просмотров 1324. Ответов 8
Метки нет (Все метки)

вот задание:
Пользовательский класс Х должен содержать необходимые элементы-данные, которые создаются в динамической области памяти. Конструктор для их создания (операция 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)));
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.09.2009, 01:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Зачем нужны конструктор и деструктор класса? (C++):

Конструктор и деструктор анонимного класса - C++
Здравствуйте. Есть ли в С++ такая возможность? Очень нужна именно такая реализация класса, но если это невозможно, буду думать.

Дописать конструктор и деструктор для класса - C++
Помогите пожалуйста написать конструктор копии и деструктор, а также вызвать их, чтобы деструктор выводил на экран &quot;работает&quot; #include...

Для класса задать конструктор и деструктор - C++
Ребята,нужна помощь в написании программы. Для класса задать конструктор(для выделения памяти,открытия файлов,задания начальных значений...

Конструктор (деструктор) у класса, не имеющего тип - C++
Можно ли объявить и определить конструктор у класса, который не имеет тип? То есть у меня в программе всего 1 экземпляр этого класса,...

Создание класса с перегрузкой операторов конструктор и деструктор - C++
Создать класс времени (Time) содержащий закрытую переменную-член хранящую целое значение времени интервала в секундах. Интерфейс класса...

Нужно ли прописывать конструктор и деструктор для чисто виртуального абстрактного класса - C++
Всем привет! Порылся в интернете, но не смог найти конкретного ответа на свой вопрос. Возможно я просто не смог грамотно сформулировать...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
27.09.2009, 01:41 #2
Ошибка "undeclared identifier" значит, что компилятор, по-русски говоря, не понимает, что это за переменные res, x, y да ещё и z
Неопознанные идентификаторы- вот как это переводится.
А оно на самом деле так.

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

А ты просто решил к этим переменным обратиться, так не пойдёт.
...Вообще книжки читать надо. Там иногда полезные вещи пишут.
0
easybudda
Модератор
Эксперт CЭксперт С++
9622 / 5570 / 946
Регистрация: 25.07.2009
Сообщений: 10,695
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
0
YAUHEN
146 / 128 / 6
Регистрация: 29.07.2008
Сообщений: 506
27.09.2009, 15:06  [ТС] #4
kravam, на сколько я понимаю что я написал в проге я и пытаюсь обратится к этим переменным через friend функцию.
easybudda с выражением проблем не должно быть тк в предыдущей лабе оно работало.
0
easybudda
Модератор
Эксперт CЭксперт С++
9622 / 5570 / 946
Регистрация: 25.07.2009
Сообщений: 10,695
27.09.2009, 15:22 #5
YAUHEN, Да она у меня и без "выражения" вылетает. Кстати, самому интересно, с какого перепуга...
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
27.09.2009, 15:59 #6
YAUHEN, прошу прощенья, не заметил.
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
27.09.2009, 20:36 #7
Всё дело в передаче аргумента. Напиши в функциях не (X obj), а (X &obj), а ещё лучше (const X &obj).
Если интересна суть происходящего, то дело вот в чём - при передаче объекта в функцию срабатывает конструктор копирования. Поскольку он не объявлен явно, срабатывает созданная компилятором версия, поэлементно копирующая члены в новый объект. В нашем случае - указатели. При выходе из функции срабатывает деструктор аргумента и выделенная память (на которую ссылается как объект параметра, так и породивший его объект, живущий в функции main) уничтожается, после чего указатели объекта, сидящего в функции main начинают указывать "в никуда". Дальнейшее обращение по данным указателям и вызывает исключительную ситуацию.
1
easybudda
Модератор
Эксперт CЭксперт С++
9622 / 5570 / 946
Регистрация: 25.07.2009
Сообщений: 10,695
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;
}
работает. При чём с оригинальной версией функции.
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
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 Посмотреть сообщение
но вылетает на функции
на какой? У меня вот не вылетает нигде. Мусор есть, а вылетать не вылетает.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.03.2013, 13:34
Привет! Вот еще темы с ответами:

При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О - C++
Вот такой кодclass A { public: A(){} virtual ~A(){} }; class C { public:

Конструктор инициализации, конструктор копирования, деструктор - C++
Я сделал почти задание по перегрузке операторов. Осталось одно, тоесть три: конструктор инициализации, конструктор копирования, деструктор....

Создать класс "Вектор" и реализовать конструктор по умолчанию, конструктор копирования и деструктор - C++
Всем доброго времени суток! нужна ваша помощь! нужно создать класс вектор и реализовать конструктор по умолчанию, копирования и...

Конструктор класса не видит конструктор по умолчанию другого класса - C++
Ошибка, естественно, в Classes.cpp, в строке 20. Ругается, что у класса TailNode нет конструктора по умолчанию, хотя он там, конечно, есть....


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.03.2013, 13:34
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru