Проблема проектирования класса C ++ - PullRequest
0 голосов
/ 28 августа 2009

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

Я решил сохранить переменные, связанные с протоколом (например, жетоны билета, nonce и т. Д.), Как статические переменные-члены в служебном классе, как показано ниже:

class MsnUtility
    {
    public:
        static void SetChallengeStringL ( const char *string );

        static const char* GetChallengeString ( );

        static void SetContactTicketL ( const char *ticket );

        static const char* GetContactTicket ( );

    private:

        MsnUtility();

    static char *iChallengeString;

        static char *iContactTicket;
    };

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

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

Я также открыт для альтернативных проектных предложений.

Ответы [ 5 ]

1 голос
/ 28 августа 2009

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

class MsnUtility
{
public:
  static MsnUtility& Instance()
  {
    return instance;
  }
public:
  void SetChallengeStringL(const char* cstring)
  {
    if (iChallengeString) delete[] iChallengeString;
    iChallengeString = new char[strlen(cstring) + 1];
    strcpy(iChallengeString, cstring);
  }
  const char* GetChallengeString() const 
  {
    return iChallengeString;
  }
  void SetContactTicketL(const char* ticket)
  {
    if (iContactTicket) delete[] iContactTicket;
    iContactTicket = new char[strlen(ticket) + 1];
    strcpy(iContactTicket, ticket);
  }
  const char* GetContactTicket() const
  {
    return iContactTicket;
  }
private:
  MsnUtility() : iChallengeString(0), iContactTicket(0) { }
  ~MsnUtility()
  {
    if (iChallengeString) delete[] iChallengeString;
    if (iContactTicket) delete[] iContactTicket;
  } 
  char* iChallengeString;
  char* iContactTicket;
  static MsnUtility instance;
};

Вы можете использовать класс следующим образом:

// test.cpp

#include <iostream> // or whatever is available on your development platform.
#include "MsnUtility.h"

MsnUtility MsnUtility::instance;

int
main()
{
  MsnUtility& u = MsnUtility::Instance();
  u.SetContactTicketL("ticket");
  u.SetChallengeStringL("ch");
  std::cout << u.GetContactTicket() << ", " << u.GetChallengeString() << '\n';
  return 0;
}
1 голос
/ 28 августа 2009

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

Я думаю, что лучшей идеей в этом случае было бы иметь класс синглтона со всеми необходимыми токенами. Сделайте этот класс глобально доступным, предоставьте необходимые setters \ getters для манипулирования токенами. Затем, когда dtor класса singleton вызывается при выходе из программы, вы можете освободить память.

Что-то в следующих строках: -

class TokenDict  {
public:
  static TokenDict& instance() {
    static TokenDict instance;
    return instance;
  }
  // getters \ setters for tokens
  void setToken(char* tptr) {
    if(token1)
      delete[] token1;
    // allocate memory for new token here
    token1 = new char[strlen(tptr) + 1];
    // copy tptr into token1
  }
  char const* getToken() const { return token1; }
private:
   ~TokenDict()
  {
    delete[] token1;
  }
  TokenDict() : token1(0) // ctor hidden
  { }
  TokenDict(TokenDict const&); // copy ctor hidden
  TokenDict& operator=(TokenDict const&); // assign op. hidden
  char* token1;
};
0 голосов
/ 28 августа 2009

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

0 голосов
/ 28 августа 2009

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

0 голосов
/ 28 августа 2009

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

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