класс-оболочка указателя - ведет себя как необработанный указатель - PullRequest
3 голосов
/ 24 августа 2011

Мне нужен класс-оболочка для указателей, который действует так же, как необработанный указатель, но также сохраняет специальное целое число вместе с указателем (индекс типа в массиве, из которого он получен)

Мне удалось заставить его вести себя в основном как указатель. Я знаю, что решение для сравнения указателей может быть неоптимальным, но это не моя главная проблема. Я хочу, чтобы обертка была построена с 2 параметрами (указатель, indexToArr), если указатель не равен NULL - тогда меня не волнует indexToArr.

Проблема, которую я пытаюсь решить, состоит в том, как разрешить возврат NULL, как позволяет обычный указатель. Текущее решение использует ASSERT. Но я хочу что-то, что работает во время компиляции. что-то в духе специализированного шаблонного метода - в качестве аргумента допускается только NULL.

Текущая версия:

class PtrWrapper
{
public:
    PtrWrapper(Type* ptr, int indToArr) 
        : m_ptr(ptr), m_indexToArr(indToArr){}

    //allow returning NULL, only NULL
    PtrWrapper(Type* ptr) : m_ptr(NULL), m_indexToArr(-1) {ASSERT(ptr == NULL);}

    Type* operator->() const {return m_ptr;}
    Type& operator*() const {return *m_ptr;}
    int IndexToArr() const {return m_indexToArr;}

    //for pointer comparison
    operator Type*() const {return m_ptr;}

private:
    Type* m_ptr;
    int m_indexToArr;
};

Есть идеи, предложения?

Спасибо, Leo

Ответы [ 2 ]

5 голосов
/ 24 августа 2011
template<typename Type>
class PtrWrapper
{
    typedef struct { } NotType;
public:
    Ptr() { }
    Ptr(const NotType* nullPtr) { }
    Ptr(Type* p, int index) { }
};

Вы можете использовать тот факт, что литерал NULL / 0 может быть автоматически приведен к любому типу указателя. Создайте тип, который НЕ T, и конструктор, который принимает единственный указатель на этот тип, который никто никогда не будет использовать. Теперь вы можете обрабатывать PtrWrapper<T> x(NULL); явно.

Конечно, как говорили другие, это сработает, только если NULL известно во время компиляции.

1 голос
/ 24 августа 2011

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

Выполните следующие действия:

PtrWrapper(Type* ptr) : m_ptr(ptr), m_indexToArr(0) {ASSERT(ptr != NULL);}
PtrWrapper() : m_ptr(NULL), m_indexToArr(-1) {ASSERT(ptr == NULL);}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...