C ++ состав лучшие практики - PullRequest
2 голосов
/ 06 ноября 2011

У меня проблемы с выбором лучшего решения моих проблем.В настоящее время я работаю над своим первым проектом C ++, я использую Qt BTW, но, поскольку я являюсь разработчиком .NET, есть некоторые вещи, которые меня раздражают в отношении C ++ :).Как вы все знаете, в мире сбора мусора, таком как Java или .NET, лучше всего использовать Dependency Injection для классов слабой связи, делая его более тестируемым и обслуживаемым, но я понятия не имею, что делать в C ++.В C ++ нет GC, поэтому мы должны позаботиться о каждом выделении памяти, и это вызывает слишком много вопросов.

Например, у меня есть класс «Правило», в котором есть поле члена, указывающее на «Приложение»."class:

class Rule : public QObject
{
public:
    explicit Rule(QObject *parent = 0);

    unsigned int id();
    void setId(unsigned int id);

    Application* application();
    void setApplication(Application* application)
    {
        m_Application = application
        m_Application->setParent(this);
    }

};

В конструкторе я назначаю NULL переменной экземпляра приложения.В setApplication я назначаю это в качестве родителя для приложения.Экземпляр приложения будет автоматически удален при уничтожении Rule (родительского) благодаря Qt.Это хороший подход?было бы лучше, если бы я использовал умный указатель, такой как QSharedPointer вместо Application *?Какой у вас опыт, в чем недостатки, каков наилучший подход.Я с удовольствием выслушаю ваши советы.Также здесь есть еще одна сложная часть.Что, если я передам этот класс другому разработчику в команде или я опубликую библиотеку.Разработчик может легко написать что-то вроде:

Application app;
app.setId(1);
Rule rule;
rule.setApplication(&app); //When rule will be destroyed, the program would crash because app is allocated on the stack.

или

Application *app = new Application();
app->setId(20);
Rule *rule = new Rule();
rule->setApplication(app);
Application *appToAnotherLocation = new Application();
rule->setApplication(appToAnotherLocation); // This wouldn't result in memory leak, because app is already child of rule, but if I didn't used Qt this would be a problem... probably :)

А что насчет умных указателей?Есть ли какие-то правила, когда мы должны их использовать, а когда нет?У меня есть интерфейс IRepository, который всегда возвращает QSharedObject вместо указателей.Это хороший подход или я злоупотребляю им?

class IRepository
{
public:
    virtual bool save(Application & application) = 0;
    virtual bool save(Rule & rule) = 0;
    virtual bool save(History & history) = 0;

    virtual bool remove(Application & application) = 0;
    virtual bool remove(Rule & rule) = 0;
    virtual bool remove(History & history) = 0;

    virtual QSharedPointer<Application> getApplication(unsigned int id) = 0;

    virtual QSharedPointer<Rule> getRule(unsigned int id) = 0;
    virtual QList< QSharedPointer<Rule> > getRules(unsigned int applicationId) = 0;

    virtual QSharedPointer<History> getHistory(unsigned int id) = 0;
    virtual QList< QSharedPointer<History> > getHistories(unsigned int applicationId) = 0;
    virtual QList< QSharedPointer<History> > getHistories(unsigned int applicationId, QDateTime dateFrom, QDateTime dateTo) = 0;
};

Спасибо.Ваша помощь очень ценится.

Ответы [ 2 ]

1 голос
/ 07 ноября 2011

Как уже упоминалось другими, используйте умные указатели, чтобы выразить право собственности.При использовании Qt вы должны прочитать о Управление памятью в Qt?

1 голос
/ 06 ноября 2011

субъективное мнение;

Во-первых: как сказал Крис, умный указатель - очень хорошая альтернатива для утечек памяти.Старайтесь всегда использовать их.

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

В вашем примере правило «не должно» удалять указатель приложения.Подумайте о своем дизайне: я не понимаю, почему Правило является родителем Приложения.Я полагаю, что приложение может работать с множеством правил.

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