2
#pragma once
using namespace std;
#include <memory>
template <typename E>
class Link
{
private:
    static unique_ptr<Link<E>> freelist; // Pointer to the freelist head
                              // How to release the memory if I use Link<E>*

public:
    E element;
    Link *next;

    Link(const E &eleval, Link *nextval = nullptr)
        : element(eleval)
        , next(nextval) {}
    Link(Link *nextval = nullptr) : next(nextval) {}

    void *operator new(size_t)
    {
        if (freelist == nullptr) return ::new Link;
        unique_ptr<Link<E>> temp = freelist;
        freelist = freelist->next;
        return temp.get();
    }

    void operator delete(void* ptr)
    {
        ((Link<E>*)ptr)->next = freelist.get();
        freelist = make_unique<Link<E>>(ptr);
    }
};

template <typename E>
unique_ptr<Link<E>> Link<E>::freelist = nullptr;

I previously use Link* to store the address of freelist, but then I found that I couldn't release the memory of freelist. So I decided to use unique_ptr to store it since the memory will be automatically released.

However, I got into this problem:

    void operator delete(void* ptr)
    {
        ((Link<E>*)ptr)->next = freelist.get();
        freelist = *reinterpret_cast<unique_ptr<Link<E>>*>(ptr);
    }

In this function I was trying to convert void* to unique_ptr and vice versa, But I got this error when I compile the code:

Error C2679 binary '=': no operator found which takes a right-hand operand of type 'Link *' (or there is no acceptable conversion)

Is there any way other than this to convert from raw pointer to smart pointer?

Charlie Lee
  • 123
  • 6
  • You really should write a `node` type and have that handle storing the pointer to the next object and the data. Then you implement `Link` using `node`. – NathanOliver Oct 08 '18 at 15:27
  • Is the pointer you pass to `delete` really of type `unique_ptr>*`? If not then the cast is invalid. – Some programmer dude Oct 08 '18 at 15:27
  • 2
    Smart ”pointers” are not pointers. – molbdnilo Oct 08 '18 at 15:28
  • 1
    Don't use `#pragma once` ([link](https://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards/34884735#34884735)) and don't put `using namespace std;` in a header (and I'd refrain from putting in a source file as well, even for toy code). – Eljay Oct 08 '18 at 15:32
  • @Eljay "and I'd refrain from putting in a source file as well, even for toy code" Why? – George Oct 08 '18 at 15:33
  • 2
    @George See [Why is “using namespace std” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Some programmer dude Oct 08 '18 at 15:34

0 Answers0