Как обрабатывать большие структуры указателей - PullRequest
0 голосов
/ 28 февраля 2012

Я пишу приложение, которое передает данные через внешний сервис на некоторый сервер. Есть определенная структура, которую я должен использовать для этого, и она выглядит так:

class A {
    B *b; // Another class built the same principle
    C *c; // And another one
    ...
};

и это где-то сводится к

class XY {
    double *some_val;
    std::string *another_val;
    ...
};

Проблема, с которой я сталкиваюсь, заключается в том, что я имею дело только с указателями указателей указателей, если хотите, и я пока не выяснил, как лучше всего справиться с этими структурами.

Я мог бы сам справиться с управлением памятью с помощью new и delete, но потом мне пришлось бы провести большую очистку, и, возможно, я забыл что-то почистить, а утечки в моей программе, по моему мнению, слишком велики.

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

Умные указатели также приходили мне в голову, но, поскольку они в основном являются классами, обертывающими указатель, мне также пришлось бы объявлять их заранее, преимущества по сравнению с предыдущим методом кажутся небольшими.

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

Обновление:

Если кто-то столкнется с той же проблемой, это мой подход сейчас (хотя я все еще думаю, что это грязно!):

#include <boost/shared_ptr.hpp>
#include <boost/any.hpp>

class A {
    B *b_;
    double *d_;
};

int main() {
    std::vector<boost::any> vp;

    // Create instance of A
    vp.push_back(boost::shared_ptr<A>(new A));
    A *a = boost::any_cast<boost::shared_ptr<A> >(vp.back()).get();

    // Create instance of B in A
    vp.push_back(boost::shared_ptr<B>(new B));
    a->b_ = boost::any_cast<boost::shared_ptr<B> >(vp.back()).get();

    // etc.

    return 0;
}

Обновление 2:

#include <boost/shared_ptr.hpp>

typedef std::vector<boost::shared_ptr<void> > MemoryManager;

template <class T> T* create_managed(T *ptr, MemoryManager &memorymanager) {
    memorymanager.push_back(boost::shared_ptr<T>(ptr));
    return boost::static_pointer_cast<T>(memorymanager.back()).get();
}

int main() {
    MemoryManager mm;
    A *a = create_managed(new A, mm);
    a->b_ = create_managed(new B, mm);
    return 0;
}

Ответы [ 2 ]

5 голосов
/ 28 февраля 2012

Подумайте об использовании умных указателей , у них есть большое преимущество:

Чтобы быть умнее обычных указателей, умные указатели должны делать то, чего не делают обычные указатели.Что бы это могло быть?Вероятно, наиболее распространенные ошибки в C ++ (и C) связаны с указателями и управлением памятью: висячие указатели, утечки памяти, ошибки выделения и другие радости.Умный указатель позаботится об этих вещах и может сэкономить много аспирина ...

1 голос
/ 28 февраля 2012

Умные указатели - это то, что вам нужно.Есть много их реализации, или вы можете написать свой собственный.При правильном использовании их вам не нужно заботиться об удалении ваших классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...