2

How to code my program to has flexibility to receive custom allocator in advance?

I coded some allocators, but not sure whether I will really need it.
However, I know for sure that if my custom allocator will be plugged-in, I want to use it in some certain parts.

Example

For example, int* B::db should use custom allocator (myNew/myDelete),
while all std::vector should use standard allocator.

While I still don't plug my custom allocator, I wish my program will use standard new/delete as default.

#define myNew new
#define myDelete delete
class B{ //B should not be a template class
    int* db=nullptr;
    std::vector<float> something; //<- let it use default new/delete
    public: B(){
        db=myNew int[5];   //work like "db=new int[5];"
    }
    public: ~B(){
        myDelete[] db;     //work like "delete[] db;"
    }
};

If I want plug a custom allocator later, I can just change the #define.

Note: B should not be a template class.

Question

I am not sure if this is a correct way. I am still very new to allocator.
I also want to avoid macro if possible.
Is it a good solution? Are there solutions without macro?

I can let my program just use new/delete as default, and I can refactor it later.
However, it will probably be a mental-breaking work in the future.

Note: Most Q/A seem to focus on overloading the global new/delete. That is not what I want. :-

Sorry if this question is too newbie.
I haven't found any good tutorial/information about using allocator in real practice.

I have also read (they are just theory of allocator + code) :-

Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67

1 Answers1

2

B may have to stay a non-template. But it doesn't mean you can't write a template to help. And you may as well facilitate RAII while you're at it.

template<typename T>
class my_new_heap_array {
  T *ptr;
public:
  operator T*() const { return ptr; }

  my_new_heap_array(std::size_t sz) 
    : ptr(myNew T[sz])
  {}

  ~my_new_heap_array() { myDelete[] ptr; }
};

class B { //B should not be a template class
    my_new_heap_array<int> db;
    std::vector<float> something; //<- let it use default new/delete
    public:
    B()
      :db(5)
    { }
};

In general, so long as you program with separation of concerns in mind, you'd find it easier to change behaviors more easily. B needs to decide on what allocator to use, but it shouldn't be concerned with how to use it. That concern falls on the helper class. And if B needs to use another allocator some day, then just switch out the helper class for another.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • It seems to be a right way, thank. I have never seen any book do like this. Where can I find more information / what is this technique call? – javaLover May 16 '17 at 05:35
  • 1
    @javaLover - Mmmm, Iv'e been treating this as C++ folklore for so long I forgot where I first saw it. I think the general design principal of "separation of concerns" is the thing to note. If you find yourself thinking how you'd customize something in a class, it's usually a sign that your class is not the one that should be concerned with how it's done, but rather another utility class that is composed into your business logic. [/ramble]. – StoryTeller - Unslander Monica May 16 '17 at 05:40
  • 1
    Your speech is full of wisdom as always. It makes me look all programming in a more modular way. There are a lot of other things to think of, after I read your comment. Thank. – javaLover May 16 '17 at 05:44