335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
1

Статический указатель класса на объект этого же класса

16.08.2015, 20:36. Показов 2325. Ответов 25
Метки нет (Все метки)

Не пойму: что в этом коде не так?
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
#include <iostream>
#include <cstdlib>
 
using namespace std;
 
struct A
{
    int x;
    int y;
 
    static A* pA;
    
    A& f()
    {
        pA = new A();
        return *pA; 
    }
 
    A() : x(0), y(0)
    {
        cout << "Create!" << endl;
    }
 
    ~A()
    {
        cout << "Destroyed!" << endl;
        delete pA;
    }
};
 
A* A::pA = 0;
 
int main()
{
    A a;
    A b = a.f();
    
    system("pause");
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.08.2015, 20:36
Ответы с готовыми решениями:

Указатель метода класса в другом методе этого класса
Здравствуйте. Как можно передать в методе класса указатель на другой метод этого же класса....

Использование в качестве поля класса указатель на объект другого класса
Ошибка в названии - &quot;указателЯ&quot; Вот, пытаюсь освоить ООП (пока только учусь): создаю класс...

Указатель на объект базового класса и адрес объекта производного класса
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; }...

Правда, что указатель класса-наследника не может указывать на объект класса-родителя?
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может...

25
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
16.08.2015, 20:49 2
Лучший ответ Сообщение было отмечено nord_v как решение

Решение

замените:

C++
1
2
3
4
5
A& f()
    {
        pA = new A();
        return *pA; 
    }
на:

C++
1
2
3
4
5
6
A& f()
    {
        if(!pA)
            pA = new A();
        return *pA; 
    }

но ещё лучше, если заменить статические поля на локальные статики:

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
#include <iostream>
#include <cstdlib>
 
using namespace std;
 
struct A
{
    int x;
    int y;
 
    //static A* pA;
    
    A& f()
    { 
        static A a;
        return a;
    }
 
    A() : x(0), y(0)
    {
        cout << "Create!" << endl;
    }
 
    ~A()
    {
        cout << "Destroyed!" << endl;
    }
};
 
int main()
{
    A a;
    A b = a.f();
    
    system("pause");
    return 0;
}
такой код проще и безопаснее.

Добавлено через 3 минуты
Цитата Сообщение от nord_v Посмотреть сообщение
A& f()
* * {
* * * * pA = new A();
* * * * return *pA;
* * }
здесь вы создаете объект, который живет по указателю

а здесь:

C++
1
2
3
4
5
~A()
    {
        cout << "Destroyed!" << endl;
        delete pA;
    }
в диструкторе уничтожаете объект по указателю.

в результате, процедура уничтожения объекта задействует диструктор,
в которой опять дергается операция уничтожения,

которая задействует диструктор, в которой опять дергается операция уничтожения...


итого: вечная рекурсиия, пока стек не переполнится
1
7275 / 6220 / 2833
Регистрация: 14.04.2014
Сообщений: 26,871
16.08.2015, 20:52 3
delete из деструктора убери.
1
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 20:56  [ТС] 4
Цитата Сообщение от hoggy Посмотреть сообщение
замените:
Ничего не меняет с этим:
Цитата Сообщение от hoggy Посмотреть сообщение
итого: вечная рекурсиия, пока стек не переполнится
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
16.08.2015, 20:59 5
Цитата Сообщение от nord_v Посмотреть сообщение
Ничего не меняет с этим:
верно.

но дело не в этом.

рассмотрим ваш код:

C++
1
2
3
4
5
6
7
// каждый раз, когда вы вызываете эту функцию
 A& f()
    {
        pA = new A();  //<--- указатель смотрит на новый адрес
        return *pA; 
    }
// итого: утечка памяти

C++
1
2
3
4
A a;
a.f(); //<-- первый вызов создаст объект
a.f(); //<-- второй вызов опять создаст объект
  // но при этом удалить старый объект забыли
0
7275 / 6220 / 2833
Регистрация: 14.04.2014
Сообщений: 26,871
16.08.2015, 21:01 6
В чём задача? К чему эти мутные манипуляции?
0
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 21:05  [ТС] 7
Цитата Сообщение от nmcf Посмотреть сообщение
delete из деструктора убери.
Так память не освобождается.
Цитата Сообщение от hoggy Посмотреть сообщение
A a;
a.f(); //<-- первый вызов создаст объект
a.f(); //<-- второй вызов опять создаст объект
* // но при этом удалить старый объект забыли
Цитата Сообщение от hoggy Посмотреть сообщение
рассмотрим ваш код:
Это не про мой пример, в коде один вызов функции класса.

Добавлено через 52 секунды
Цитата Сообщение от nmcf Посмотреть сообщение
В чём задача? К чему эти мутные манипуляции?
Вопрос теоретический, не понял: почему деструктор бесконечно вызывается. Укзатель в единственном экземпляре, указывает на один объект, а деструктор бесконечно работает.
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
16.08.2015, 21:11 8
Цитата Сообщение от nord_v Посмотреть сообщение
Это не про мой пример, в коде один вызов функции класса.
ну если вы считаете,
что это нормально - конструировать функцию,
которая потенциально способна допускать утечки памяти,
и корректность работы целиком зависит от вызывающей стороны - дело ваше.

однако в миру такого рода код называют "говнокодом".

вы спросили, что не так с кодом - я вам ответил.
дыра в безопасности, и бесконечная рекурсия при удалении объекта.
0
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 21:12  [ТС] 9
Цитата Сообщение от nmcf Посмотреть сообщение
delete из деструктора убери.
То есть так:
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
struct A
{
    int x;
    int y;
 
    static A* pA;
    
    A& f()
    {
        if(!pA)
            pA = new A();
        return *pA; 
    }
 
    A() : x(0), y(0)
    {
        cout << "Create!" << endl;
    }
 
    ~A()
    {
        cout << "Destroyed!" << endl;
        //delete pA;
    }
};
 
A* A::pA = 0;
 
int main()
{
    A a;
    A b = a.f();
    
    delete A::pA;
    
    system("pause");
    return 0;
}
0
7275 / 6220 / 2833
Регистрация: 14.04.2014
Сообщений: 26,871
16.08.2015, 21:12 10
Ну какой он теоретический, если ты сам не понимаешь что хочешь.
Цитата Сообщение от nord_v Посмотреть сообщение
почему деструктор бесконечно вызывается
Потому что delete подразумевает вызов деструктора, а в нём снова delete.
0
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 21:29  [ТС] 11
Понятно, спасибо всем за разъяснения.

Добавлено через 12 минут
Цитата Сообщение от hoggy Посмотреть сообщение
ну если вы считаете,
что это нормально - конструировать функцию,
которая потенциально способна допускать утечки памяти,
и корректность работы целиком зависит от вызывающей стороны - дело ваше.
hoggy, не сердитесь, я же написал, что вопрос теоретический, поэтому и пример кода - теоретический.
Цитата Сообщение от hoggy Посмотреть сообщение
// каждый раз, когда вы вызываете эту функцию
C++
1
2
3
4
5
A& f()
{
     pA = new A(); *//<--- указатель смотрит на новый адрес
     return *pA; 
}
// итого: утечка памяти
Если этот объект мне уже не нужен, это будет утечкой памяти?

Добавлено через 2 минуты
Цитата Сообщение от nmcf Посмотреть сообщение
Ну какой он теоретический, если ты сам не понимаешь что хочешь.
Сообщение от nord_v
почему деструктор бесконечно вызывается
Потому что delete подразумевает вызов деструктора, а в нём снова delete.
nmcf,
Цитата Сообщение от nord_v Посмотреть сообщение
Понятно, спасибо всем за разъяснения.
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
16.08.2015, 21:33 12
Цитата Сообщение от nord_v Посмотреть сообщение
Если этот объект мне уже не нужен, это будет утечкой памяти?
дважды вызвал функцию - получил утечку.

вообще ваш оригинальный код
не умеет корректно удалить объект по статическому указателю.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.08.2015, 21:36 13
Цитата Сообщение от nord_v Посмотреть сообщение
Не пойму: что в этом коде не так?
А что ? Нормальный гавнокод... так держать ...
Тут даже обсуждать нечего.
0
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 21:40  [ТС] 14
Цитата Сообщение от hoggy Посмотреть сообщение
дважды вызвал функцию - получил утечку.
Кто-то писал, что контролируемая утечка - это уже и не утечка?
Цитата Сообщение от nord_v Посмотреть сообщение
Если этот объект мне уже не нужен,
Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
А что ? Нормальный гавнокод... так держать ...
Avazart, это не код, это теоретическая конструкция, будьте снисходительны к совсем начинающему.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.08.2015, 21:52 15
Цитата Сообщение от nord_v Посмотреть сообщение
Avazart, это не код, это теоретическая конструкция, будьте снисходительны к совсем начинающему.
Теоретическая конструкция как не надо писать код?
Что она вообще по вашему должен делать этот код?
Возможно если бы было указано то что он хотелось сделать- был бы смысл комментировать код, а так в мусорку.
0
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 21:54  [ТС] 16
Цитата Сообщение от Avazart Посмотреть сообщение
Что она вообще по вашему должна делать?
Ни хрена она не должна делать.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.08.2015, 21:56 17
Цитата Сообщение от nord_v Посмотреть сообщение
Ни хрена она не должна делать.
Тогда вам к индусам, а кому интересен код который ничего не делает?
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
16.08.2015, 21:58 18
Цитата Сообщение от nord_v Посмотреть сообщение
Кто-то писал, что контролируемая утечка - это уже и не утечка?
в вашем случае она - не контролируемая,
поскольку их отсутствие не гарантируется инвариантом.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.08.2015, 22:05 19
Цитата Сообщение от nord_v Посмотреть сообщение
контролируемая утечка
А что есть такая?

Что мешает сделать так:
C++
1
static std::shared_ptr<A>  a;
Хотя по сути может тут и static лишний тогда, опять же знать бы задачу.

Ну или банально обвернуть указатель в объект другого класса.
0
335 / 183 / 80
Регистрация: 22.08.2013
Сообщений: 724
16.08.2015, 22:14  [ТС] 20
Цитата Сообщение от Avazart Посмотреть сообщение
А что есть такая?
Это, как бы, утечка, которая не является утечкой: Что считать утечкой памяти?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.08.2015, 22:14
Помогаю со студенческими работами здесь

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

Создание статической функции класса, которая принимает экземпляр этого же класса как объект
Привет. Есть такой код class Model { public: Model(); Model(int verticesSize, int facesSize);...

Индексация массива класса, через объект этого класса
class A{ char c;//? - размер массива public: A(int C){c;} }; int main(){ A a(5);//вносим...

В конструктор класса передать объект этого класса
Вопрос на засыпку :) Как в конструктор класса передать объект этого класса? Т.е. class A {...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru