带有模板的 c++ 析构函数:T 可以是指针,也可以不是指针
c++ Destructor with templates: T could be a pointer or not
我在编写模板类时遇到了一个小问题 win C++.问题相当简单:我不知道是否要对参数化类型进行delete
,因为它可以,或者不能,是一个指针。
我已经看到这个:模板类c中的析构函数:如何删除可能是指针或不是指针的字段?
我已经实现了第一个解决方案,但这需要我专注于整个班级,所以这意味着我必须有 2 个类:
template<class T>
class Node {
private:
T _content;
public:
Node(const T c);
~Node();
};
和
template<class T>
class Node<T*> {
private:
T _content;
public:
Node(const T c);
~Node();
};
我只想拥有第二个版本,并且只专门介绍析构函数,如下所示:
template<class T>
class Node<T*> {
private:
T _content;
public:
Node(const T c);
~Node();
};
template <class T>
Node<T>::~Node() {
while(!_adjacent.isEmpty()) {
disconnectFrom(_adjacent.first());
}
}
template <class T>
Node<T*>::~Node() {
while(!_adjacent.isEmpty()) {
disconnectFrom(_adjacent.first());
}
delete _content;
}
但随后我收到以下错误:
Node.hpp:43:17: error: invalid use of incomplete type ‘class Node<T*>’
Node.hpp:8:7: error: declaration of ‘class Node<T*>’
有没有办法只专门化构造函数以避免有 2 个类(我的 Node 类比我在这里显示的要大得多)?
谢谢!
一个解决方案是使用特征类:
template<typename T> struct delete_traits
{
void destroy(T&) {}
};
template<typename T> struct delete_traits<T*>
{
void destroy(T* p) { delete p; }
};
然后在你的类析构函数中写入
delete_traits<T>::destroy(_contents);
除了不必专门化Node
模板之外,它还具有额外的优势,即您只需添加另一个模板专用化,即可轻松添加其他方法来销毁内容,而无需触及您定义Node
的文件:
// assumes that mylib_handle is a truly different type, maybe a C struct
// from the C interface of a library
template<> struct delete_traits<mylib_handle>
{
void destroy(mylib_handle& h) { mylib_handle_free(m); }
};
根本不专门研究 Node。只需为您的意图使用正确的类型:
- 唯一所有权:
std::unique_pointer<T>
。 - 共享所有权:
std::shared_pointer<T>
。- 共享所有权的反向链接:
std::weak_pointer<T>
.
- 共享所有权的反向链接:
- 无所有权:原始指针
如果需要特定的析构函数,这些模板具有该参数。
此外,您可以将它们用于句柄等,即使它们没有命名为指针。
似乎你想要这个:
template<class T>
class Node {
private:
T _content;
public:
Node(const T c) : _content { c } {}
~Node() {}
};
template<class T>
class Node<T*> {
private:
T* _content;
public:
Node(const T* c) : _content { c } {}
~Node() { delete _content; }
};
而且,正如@Constructor所说,不,你不能只专注于析构函数,你必须做整个班级......但是,如果类更大,则可以将通用性重构为基类,这样就可以得到如下内容:
template<class T>
class BaseNode {
private:
template<class> friend class Node;
T _content;
public:
BaseNode(T c) : _content { c } {}
~BaseNode() {}
};
template<class T>
struct Node : BaseNode<T> {
Node(T c) : BaseNode<T>(c) {};
~Node() {}
};
template<class T>
struct Node<T*> : BaseNode<T*> {
Node(T* c) : BaseNode<T*>(c) {};
~Node() { delete BaseNode<T*>::_content; }
};
相关文章:
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 为什么即使调用了析构函数,C++11 中的分离线程也可以执行
- 为什么即使直到最后才定义实际类型,也可以将依赖名称视为完整
- 斯塔克,堆栈,也可以在底部和顶部添加整数
- 'this'指针是否可以在 c++ 标头声明中使用?
- 重塑Microsoft的并发::d iagnostic::span,也可以检测外部跨度
- 在不工作的情况下为数组分配指针,但反过来也可以
- "fixed"大小的向量在 c++ 中也可以具有假大小(与内存大小相比)吗
- 为什么直接传递"this"指针来存档是一个错误,而另一个相同类型的指针是可以的?
- 函数指针,可以采用具有常量引用或复制参数的函数
- 为什么即使传递给函数作为参考,指针也未被分配
- 当 ParamType 既不是指针也不是引用时自动类型推断
- 更改C 的返回指针后可以删除工作
- 取消引用会导致崩溃,即使对于非 NULL 指针也是如此,原因也是如此
- 由于删除对象而导致的 Cpp 代码主线程冻结可以使用智能指针解决,也可以不使用智能指针来解决
- 张量类,它有自己的存储,但也可以映射外部指针
- 指针也可以指向常量空类或非常量类
- 为什么我们需要在运行时使用函数指针调用这些函数?我们也可以直接打电话给他们
- 带有模板的 c++ 析构函数:T 可以是指针,也可以不是指针