Класс Singleton для перемещения кучи в стек - PullRequest
0 голосов
/ 26 ноября 2011

Я написал некоторый класс, который перемещает кучу выделенных вещей в стек (надеюсь :)). Этот вызов является одиночным, потому что только этот класс должен отвечать за хранение и управление частью стека. Мой вопрос: мой код правильный? Код является правильным в смысле программирования (без ошибок компиляции, без ошибок памяти и утечек (проверено valgrind)). Но действительно ли код перемещает кучу в стек? Вот код:

stack.hpp:

class CStack{
public:
  void* getAlloc(long);
  static CStack* Instance();

private:
  static bool _data[5*sizeof(double)];
  static CStack* m_pInstance;

  CStack(){};
  CStack(const CStack&);
  CStack& operator=(const CStack&);
};

stack.cpp:

#include <iostream>
#include "stack.hpp"

CStack* CStack::m_pInstance = 0;

bool CStack::_data[ 5*sizeof(double) ] = { 1 };

CStack* CStack::Instance(){
  if (!m_pInstance)
    m_pInstance = new CStack;
  return m_pInstance;
}

void* CStack::getAlloc(long size){
  std::cout << "  CStack::getAlloc, " << _data << std::endl;
  _pos+=size;
  return &_data[0];
}

store.hpp

class CStore{
public:
  CStore();
  double* myAddr();
  void toStack();
  void out();
  ~CStore();
private:
  double *_data;
  bool _stack;
};

store.cpp:

#include <iostream>
#include <cstring>
#include "store.hpp"
#include "stack.hpp"

CStore::CStore(){
  _data = new double[4];
  _data[0] = 0.1;
  _data[1] = 1.1;
  _data[2] = 2.1;
  _data[3] = 3.1;
  _stack = 0;
}

double* CStore::myAddr(){ return _data; }

void CStore::toStack(){
  double *tmp;

  tmp = (double*)CStack::Instance() -> getAlloc(4*sizeof(double));

  memcpy(tmp, _data, 4*sizeof(double));
  delete [] _data;
  _data = tmp;
  _stack = 1;
}

CStore::~CStore(){
  if (!_stack)
    delete [] _data;
}

void CStore::out(){
  std::cout << _data[0] << " " << _data[1] << " " << _data[2] << " " << _data[3] << std::endl;
}

main.cpp:

#include <iostream>

#include "stack.hpp"
#include "store.hpp"

using namespace std;

int main(){
  CStack::Instance();
  CStore a;
  double stack;

  cout << &stack << endl;
  cout << "Adresa a " << a.myAddr() << endl;
  a.out();

  a.toStack();
  cout << "Adresa a " << a.myAddr() << endl;
  a.out();

  return 0;
}

1 Ответ

0 голосов
/ 29 ноября 2011

Нет, это полная чушь.

Прежде всего этот код даже не использует стек (если мы говорим о стеке выполнения), и вы явно неправильно поняли шаблон проектирования Singleton.

Вы используете Singleton, когда вам нужен только один экземпляр в вашей программе, но вы хотите предоставить доступ ко всем функциям этому одному экземпляру. Это как глобальная переменная, но вы можете ограничить доступ.

Во-вторых, если вам нужно использовать приведение в C ++, например:

tmp = (double*)CStack::Instance() -> getAlloc(4*sizeof(double));

Вы явно ошиблись. Не используйте void* в C ++ сейчас. Вы можете использовать его позже, когда вам станет лучше, а не сейчас.

Основной вопрос ПОЧЕМУ вы не хотите перемещать переменные в стек? если вы просто хотите выделить динамически, зачем все же ограничивать его областью действия, используйте умные указатели, такие как std :: auto_ptr.

если вы хотите создать стек и использовать его для хранения ваших двойников, вы можете написать:

#include <vector>

int foo()
{
  std::vector<double> stack;

  // push values on the stack
  stack.push_back(1.1);
  stack.push_back(1.2);
  stack.push_back(1.3);

  // remove values from the stack
  stack.pop_back();
  stack.pop_back();
  stack.pop_back();
}
...