Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Большое количество указателей на один объект.


Автор: Elfet 12.3.2010, 14:00
Всем привет! 

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

Можно как-нибудь более просто ссылаться на один объект из разных мест? И если удаляю его, то что бы можно было по всем указателем сразу узнать это? 

Заранее спасибо!

Автор: mes 12.3.2010, 14:02
shared_ptr (+ weak_ptr)

Автор: Леопольд 12.3.2010, 14:56
Цитата(mes @  12.3.2010,  14:02 Найти цитируемый пост)
shared_ptr (+ weak_ptr) 
Отличная связка. Нужно только понять как работает.
Цитата(Elfet @  12.3.2010,  14:00 Найти цитируемый пост)
Можно как-нибудь более просто ссылаться на один объект из разных мест? И если удаляю его, то что бы можно было по всем указателем сразу узнать это? 
Многопоточность? Если работа в одном потоке то, возомжно, достаточно только shared_ptr.

Автор: Elfet 12.3.2010, 15:34
Почитал про умные указатели. 

Правильно ли я понял как с ними работать? 

Код

shared_ptr<Mesh> mesh( new Mesh() );

//если мне нужно передать указатель в какую-нибудь метод, то делать так:

class Test {

weak_ptr<Mesh> mesh;

void SetMesh(weak_ptr<Mesh> &_mesh)
{
       mesh = _mesh;
}

}

Автор: Леопольд 12.3.2010, 15:55
Цитата(Elfet @  12.3.2010,  15:34 Найти цитируемый пост)
Код

shared_ptr<Mesh> mesh( new Mesh() );
//если мне нужно передать указатель в какую-нибудь метод, то делать так:
class Test {
weak_ptr<Mesh> mesh;
void SetMesh(weak_ptr<Mesh> &_mesh)
{
       mesh = _mesh;
}
}

Всё же лучше использовать конструктор.
Код
class Test {
weak_ptr<Mesh> mesh;
void Test (const shared_ptr<Mesh> &_mesh): mesh (_mesh) {}
};

Довольно специфично. Получается, что есть некий разделяемый ресурс, время жизни которого никак не зависит от объектов класса Test. Перед тем как использовать это ресурс, надо вызвать shared_ptr weak_ptr::lock(); и если этот разделяемый ресурс всё ещё существует, то заюзать его. Обычно, это надо при многопоточном программировании. Хотя, конечно, можно придумать применение и для одного потока. 

Может объяснишь для чего именно тебе это надо?

Автор: chaos 12.3.2010, 15:56
Цитата(Elfet @  12.3.2010,  12:34 Найти цитируемый пост)
Правильно ли я понял как с ними работать? 

угу и кругом проверять не прибили ли объект

Автор: mes 12.3.2010, 16:02
Цитата(Elfet @  12.3.2010,  14:34 Найти цитируемый пост)
Правильно ли я понял как с ними работать? 

предчувствуя о чем идем идет речь, скажу, что библиотеку желательно делать более свободной, и не навязывать свою политику клиенту.
т.е. предоставлять набор частей и инструментов, с помощью которых пользователь за условные 5 минут, может соорудить себе нужное здание,
а не  сдавать в аренду полузаконченный-офис, на адаптацию которого может уйти условный день. smile

Автор: Леопольд 12.3.2010, 16:12
Цитата(mes @  12.3.2010,  16:02 Найти цитируемый пост)
предчувствуя о чем идем идет речь
Фигасе, неконтролируемая телепатия? smile

Автор: Elfet 12.3.2010, 16:20
Вот такой вот пример с двумя классами Test и Over написал. 

Test:
Код

#ifndef TEST_H
#define TEST_H
#include "mesh.h"
#include <boost/shared_ptr.hpp>

class Test
{
public:
    Test();
    int testI();

    boost::shared_ptr<Mesh> mesh;
};

#endif // TEST_H

#include "test.h"

Test::Test()
    : mesh(new Mesh())
{
}

int Test::testI()
{
    return mesh->I();
}



Over:
Код

#ifndef OVER_H
#define OVER_H
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include "mesh.h"

class Over
{
public:
    Over();
    void SetMesh(boost::weak_ptr<Mesh> &_mesh);
    int Do();
private:
    boost::weak_ptr<Mesh> mesh;
};

#endif // OVER_H

#include "over.h"

Over::Over()
{
}

void Over::SetMesh(boost::weak_ptr<Mesh> &_mesh)
{
    mesh = _mesh;
}

int Over::Do()
{
    if(boost::shared_ptr<Mesh> p = mesh.lock())
    {
        return 2*p->I();
    }
    else
    {
        return -123;
    }
}



Mesh:
Код

#ifndef MESH_H
#define MESH_H
#include <iostream>

class Mesh
{
public:
    Mesh();
    ~Mesh();
    int I();
};

#endif // MESH_H

#include "mesh.h"

Mesh::Mesh()
{
    std::cout << "Mesh()" << std::endl;
}

Mesh::~Mesh()
{
    std::cout << "~Mesh()" << std::endl;
}

int Mesh::I()
{
    return 112358;
}



main.cpp
Код

#include <QtCore/QCoreApplication>
#include <iostream>

#include "test.h"
#include "over.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Test *t = new Test();

    std::cout << "testI: " << t->testI() << std::endl;

    Over *o = new Over();

    boost::weak_ptr<Mesh> weak_mesh(t->mesh);
    o->SetMesh(weak_mesh);

    std::cout << "o->Do: " << o->Do() << std::endl;

    delete t;

    std::cout << "o->Do: " << o->Do() << std::endl;


    return a.exec();
}



Выводит следующее:
Цитата

Mesh()
testI: 112358
o->Do: 224716
~Mesh()
o->Do: -123

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)