Правильно ли реализован шаблон?

269
20 октября 2017, 14:47

Работает как очистка памяти и все остальные шаблоны, без указания размера и типа, но правильно ли реализованы сами шаблоны?

namespace msafe
{
    // используется исключительно для освобождения COM объектов
    template <class T>
    void srel(T& t)
    {
        if (t)
        {
            t->Release();
            t = nullptr;
        }
    }
    // используется для удаления объектов классов, созданных пользователем/разработчиком
    template <class T>
    void sdel(T& t)
    {
        if (t)
        {
            delete t;
            t = nullptr;
        }
    }
    // используется для упрощения очистки памяти под структуры
    template <typename T>
    void* setz(T& t)
    {
        return memset(&t, 0, sizeof(T));
    }
    // используется для удаления массивов из памяти
    template <class T>
    void sdel_arr(T& t)
    {
        if (t)
        {
            delete[] t;
            t = nullptr;
        }
    }
}
Answer 1

Местами надо добавить *.

Например,

template <class T>
void srel(T*& t)
{
    if (t)
    {
        t->Release();
        t = nullptr;
    }
}
Answer 2

Вообще, Ваш код чреват ошибками выполнения. Условие в if, соответствие форм new и delete, гарантии наличия ф-ии члена Release(). Что, если, к примеру, пользователь вызовет функцию sdel() для С-массива или вообще для неуказательного типа? Будет явно неприятно.

Лучше объявляйте деструктор и в нем пишите, что Вы хотите дополнительно сделать при удалении. А если хотите работать с указателями, то используйте прокси-классы, например, std::shared_ptr, std::unique_ptr и т.п. Они позволяют при создании объекта указать пользовательский удалитель, например, некую функцию или лямбду. Правда, этого нельзя сделать, если Вы будете использовать make-функции. Также интеллектуальные указатели не работают с типами массива, поскольку у них используется инструкция delete без []. Но и это не проблема - STL изобилует контейнерами на любой вкус.

Answer 3

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

int x;
const int& crx = x;
int* px = &x;
template<class T>
void f(T t) { /* ... */ }
f(x); // T = int, в функцию передается копия x по значению
f(crx); // T = int, модификаторы const и & игнорируются
f(px); // T = int*, указатель не игнорируется

чтобы аргументу функции указать const и & для типа, необходимо прописать их явно

template<class T>
void f(const T& t) { /* ... */ }
f(x); // T = const int&, в функцию передается копия x по значению
f(crx); // T = int, модификаторы const и & на этапе вывода типа для T игнорируются, но добавляются для типа аргумента, т. к. они указаны

можно так же передавать и указатель (лучше так и делать, это показывает явное намерение, что шаблонная функция ожидает в качестве параметра указатель)

template<class T>
void f(T* t) { /* ... */ }
f(x); // ошибка при компиляции, функция принимает только указатели
f(px); // T = int*
f(&px); // T = int**

со всем этим хочу так же выделить один момент на счет отбрасывания const

template<class T>
void f(T t) { /* ... */ }
const int* const cpcx = *x; // константный указатель на константный int
f(x); // T = const int*, отбросился const, который отвечает за константность указателя, но остался тот, который отвечает за константность того, что лежит по этому указателю
READ ALSO
ошибка при использовании typedef

ошибка при использовании typedef

В данном коде компилятор выдает следующую ошибку:

307
Обновить XML-файл средствами QDomElement

Обновить XML-файл средствами QDomElement

Есть XML-файл со следующей структурой:

309
Код, по-разному работающий в C++03 и C++11/14

Код, по-разному работающий в C++03 и C++11/14

Понятно, что изменение смысла auto от одного стандарта к другому приводит к возможности ошибки, или, наоборот, ошибочный из-за >> в шаблоне...

360
Отображение файлов на память

Отображение файлов на память

Дано два файла, нужно переписать содержимое одного в другойПри этом надо переписывать по 1024 байта

433