再次使用模板。现在,我正在尝试编写一个Deleter
函数类,以使其类似于一种delete
的语言,因此这是我的尝试:
class Deleter
{
public:
template <typename T>
void operator()(T*) const;
};
template <typename T>
void Deleter::operator()(T* ptr) const
{
std::cout << "freeing memory...\n";
delete ptr;
}
int main()
{
int* pi = new int(7);
char* cp = new char[100];
strcpy(cp, "hi there!");
Deleter del;
del(pi); // 1- argument deduced is int*
del(cp); // 2- argument deduced is char*
std::cout << "\ndone\n";
}
我已经将调用操作符作为模板进行了重载,因此在编译时它知道参数的静态类型。 (我可以使它成为非模板,用void*
代替T。)
它工作正常,但我肯定statement 2
会导致内存泄漏,因为我将指向动态数组的指针传递给delete
,该指针对指向动态对象而不是数组的指针起作用,因为已经了解到,对于尚未使用相应的new
运算符分配的对象,调用delete是不确定的行为。
因此,我的代码中是否有变通办法,以便可以调用del[]cp;
?谢谢!
答案 0 :(得分:3)
您不能将delete
与分配给new[]
的内存一起使用,反之亦然,不能将delete[]
与分配给new
的内存一起使用。这正是std::unique_ptr
和std::shared_ptr
有专门知识来决定何时分别将delete[]
与delete
用于数组和非数组内存的原因(通过std::default_delete
模板)。
您也将必须以类似的方式来专门化Deleter
。只有您Deleter
的用户,而不是Deleter
本身,才能决定要使用哪种专业化,因为只有该用户才知道有关如何分配内存以及如何分配内存的信息。释放。
例如:
template <typename T>
class Deleter
{
public:
void operator()(T* ptr) const {
std::cout << "freeing memory using 'delete'...\n";
delete ptr;
}
};
template <typename T>
class Deleter<T[]>
{
public:
template <typename U>
void operator()(U* ptr) const {
std::cout << "freeing memory using 'delete[]'...\n";
delete[] ptr;
}
};
int main()
{
int* pi = new int(7);
char* cp = new char[100];
strcpy(cp, "hi there!");
Deleter<int> del1;
del1(pi); // uses 'delete'...
Deleter<char[]> del2;
del2(cp); // uses 'delete[]'...
std::cout << "\ndone\n";
}