C / C ++ for USE_HEAP or USE_STACK

Is there a way to define a macro (or something similar) that will allow objects to stand out on the stack or on the heap, cleanly?

eg. Current code:

A a;
a.someFunc();

The simplest sentence may be as follows, but as you can see below, it is not very simple to support 2 sets of code.

#ifdef USE_STACK
  A a;
  a.someFunc();
#elseif USE_HEAP
  A* a = new A();
  a->someFunc();
#endif

I am looking for a design template / proxy class that can be used to compile code anyway, depending on the needs of our client.

Edit: The code is used to create a library for an embedded device / (embedded) Linux / Windows Mobile. Most customers only want a stack based. Several others asked for a stack exchange for a bunch.

Thanks Charles

+3
5

: - operator->

, , :

#include <iostream>

#define USE_STACK

template <class T>
class HeapWrapper {
#ifdef USE_STACK
    T obj_;
#else
    T *obj_;
#endif
public:
#ifdef USE_STACK
    HeapWrapper() : obj_() {}

    template <class A1>
    HeapWrapper(const A1 &a1) : obj_(a1) {}

    template <class A1, class A2>
    HeapWrapper(const A1 &a1, const A2 &a2) : obj_(a1, a2) {}

    // etc

#else
    HeapWrapper() : obj_(new T()) {}
    ~HeapWrapper() { delete obj_; }

    template <class A1>
    HeapWrapper(const A1 &a1) : obj_(new T(a1)) {}

    template <class A1, class A2>
    HeapWrapper(const A1 &a1, const A2 &a2) : obj_(new T(a1, a2)) {}

    // etc
#endif

#ifdef USE_STACK
    operator const T &() const    { return obj_; }
    operator T &()                { return obj_; }
    T *operator->()               { return &obj_; }
    T& operator*()                { return obj_; }
#else
    operator const T &() const    { return *obj_; }
    operator T &()                { return *obj_; }
    T *operator->()               { return obj_; }
    T& operator*()                { return *obj_; }
#endif

    // cast operators makes this work nicely
    HeapWrapper &operator=(const T &rhs) { *obj_ = rhs; return *this;}
};


class A {
public:
    void member(int x) {
        std::cout << x << std::endl;
    }
};


int main() {
    HeapWrapper<int> x1(5);
    HeapWrapper<int> x2;
    HeapWrapper<int> x3 = x1;
    HeapWrapper<int> x4 = 3;

    std::cout << x1 << " " << x2 << " " << x3 << " " << x4 << std::endl;

    // example using a custom class members..
    HeapWrapper<A> a1;
    a1->member(5);
}
+5

- :

template <typename T>
class HeapWrapper
{
#ifdef USE_STACK
  T obj_;
#else
  T *obj_;
#endif
public:
#ifdef USE_STACK
  HeapWrapper() : obj_() {}
#else
  HeapWrapper() : obj_(new T()) {}
#endif

#ifdef USE_STACK
  const T& obj() const
  { return obj_; }

  T& obj() const
  { return obj_; }
#else
  const T& obj() const
  { return *obj_; }

  T& obj() const
  { return *obj_; }
#endif
};

, . Init(...), ​​ - ( template <typename T1, template T2, [etc]> Init(const T1 &x1, cons tT2 &x2) ):

template <typename T1>
void Init(const T1& x1)
{
#ifdef USE_STACK
  obj_.Init(x1);
#else
  obj_->Init(x1);
#endif
}

template <typename T1, typename T2>
void Init(const T1& x1, const T2& x2)
{
#ifdef USE_STACK
  obj_.Init(x1, x2);
#else
  obj_->Init(x1, x2);
#endif
}

, variadic templates :

template<typename... T>
void foo(const T&... values) {
#ifdef USE_STACK
  obj_.Init(values...);
#else
  obj_->Init(values...);
#endif
}
+2

, , . -, , , . ( ), .

, , .

"", , . - ( , (, 16 , 32 , 64 ..), , ).

+2

, .

, RAII (, ), , , (, ).

, , , , . , .

+1

, , :

#ifdef USE_STACK
  A a;
#elseif USE_HEAP
  auto_ptr<A> CAUTION_USE_OF_AUTOPTR_a( new A() );
  A& a = CAUTION_USE_OF_AUTOPTR_a.get();
#endif
a.someFunc();
0

Source: https://habr.com/ru/post/1706208/


All Articles