- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,让我更具体地说明这个问题。
通过说
check if a type's destructor can be "ignored"
我是坏人
check if a class has no side effects when it's instances die.
我在做什么:
我正在为我们的 C++ 项目编写垃圾收集库,我需要提高性能。如果我能检测到传入的类型T
在销毁时没有副作用,我就可以只检查所有活的对象,其余的都是垃圾,可以标记为“垃圾”(典型的年轻代收集技术)。但如果它有副作用,我必须扫描每一个垂死的对象并运行它的析构函数。
例如:
struct S1 {
int i;
}; // can be ignored
struct S2 {
int i;
~S2() {
}
}; // can be ignored
struct S3 {
S3() {
std::cout << "S3()" << std::endl;
}
virtual ~S3() {
std::cout << "~S3()" << std::endl;
}
}; // can not be ignored, destructor has side effect
struct S4 {
S3 s3;
}; // can not be ignored, destructor has side effect(calling s3's destructor)
// this is the most tricky one I tried and failed.
struct S5 {
S3 s3;
~S5() {
}
}; // same with S4
struct S6 : public S3 {
};// can not be ignored, super destructor has side effect
struct S7 : public S1 {
};// can be ignored, super destructor does not have side effect
struct S8 {
virtual ~S8() = default;
}; // can be ignored
// which cannot use is_trivially_destructible
struct S9 : public S8 {
}; // can be ignored
我试过将is_destructible
和is_trivially_destructible
结合起来,但这两个不能满足我的要求。特别是示例 4。
此外:欢迎任何可以解决此问题的编译器特定功能。
最佳答案
std::is_trivially_destructible
类型特征是你所需要的。看here .输出与预期不同的唯一情况是 S2
。不幸的是,C++ 缺乏将空的用户定义的析构函数视为微不足道的结构。
编辑:
没有办法从上面的特征中排除虚拟
的条件,所以剩下的唯一选择就是创建你自己的特征。这需要在用户端做额外的工作,而不是开箱即用。有几种方法可以用自定义谓词来区分用户定义的类型:
通过某种类型的继承:
class my_class : private can_be_forgotten_tag { ... };
template <typename T>
using can_be_forgotten_v =
std::is_trivially_destructible<T> ||
std::is_base_of<can_be_forgotten_tag, T>;
通过presence of a member (例如,类型别名 - 标签 - transparent comparators 是如何定义的)
根据模板特化(不限于 1. 和 2.):
template <typename T>
struct can_be_forgotten : std::is_trivially_destructible<T> {};
template <>
can_be_forgotten<S8> : std::true_type {};
更重要的是,首先应该问的问题是,这是否已经不是任何编译器自动为您做的事情(生成相同的代码,有或没有析构函数调用)。那个,最好自己检查一下。
附言我希望我们一直在考虑 placement-new,否则会出现内存泄漏。
关于C++ 模板 : check if a type's destructor can be "ignored",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58763276/
例如,下面是否泄漏? Foo ( ) { std:map myMap; myMap[std::string("Bar")] = 2983; } 我相信它不会泄漏,但找不到关于这一点的具体文
有没有办法在类析构函数之前调用字段析构函数? 假设我有 2 个类 Small 和 Big,Big 包含一个 Small 的实例作为它的字段因此: class Small { public: ~
阅读 Herb Sutter,我可以看到这一点: Guideline #4: A base class destructor should be either public and >virtual,
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 4 年前。 Improve
我只有 1 行代码,这是: pcrecpp::RE re("abc"); 在函数内部 OnBnClickedButtonGo() .这个函数在Release模式下会失败,但是在debug模式下可以正常
我最近参加了一个采访,那个人问我什么是 build 和破坏的顺序。我解释说, build 是从一个基地到另一个 child ,从一个 child 到另一个基地的破坏。 采访者很想知道从派生到基地发生破
如果我在 vector 中动态分配一个类的对象,如果我使用 clear() 是否会调用每个对象的析构函数? 最佳答案 “动态分配”到底是什么意思?如果您使用 vector那你很好。如果您通过 vect
我正在尝试使用手动内存管理来管理昂贵对象的生命周期,在我的单元测试期间,我的程序似乎因 destroy(bar) 下的主要方法中的访问冲突而崩溃在这个例子中。这是我遇到访问冲突问题的最小示例。 我不明
我只是创建一个简单的列表,然后销毁它。出了点问题,我总是收到这个恼人的错误消息: Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 代码如下: #i
class TsDatabasePool { private: TsDatabasePool(int numDBConn, std::string& DBName, std::string&
在一个项目中,我遇到了以下问题: 我有一个非常简单的继承方案(我需要继承而不是组合): 类基础 ->类DerivedA ->类DerivedB ->类DerivedC A、B 和 C 派生自 Base
我试图在我创建的矩阵类上对 + 和 = 运算符使用运算符重载。要么是构造函数或析构函数导致了问题,要么都不是(尽管我将它们中的每一个都变灰了,并且代码似乎可以工作)。有人可以帮我理解是什么导致了这种奇
我正在用 SDL 编写基于图 block 的 map ,Map 类的构造函数用于设置用于表示包含的每个 MapCell 对象的图像在里面。但是,我的 Sprite 类的析构函数有问题,该类用于释放对象
这个问题在这里已经有了答案: What destructors are run when the constructor throws an exception? (3 个答案) 关闭 8 年前。
我在 Ubuntu Trusty 上使用 C++11 和 g++4.8。 考虑这个片段 class Parent { public: virtual ~Parent() = default;
我在我们的一个客户环境中遇到问题 - 当我在 OnAppExit(或析构函数)中使用 AfxGetApp()->WriteProfileString 时它不起作用。我无法在任何地方复制它。我追踪到 O
C# Language Specification 3.0 的第 10.13 节,析构函数声明如下: Destructors are not inherited. Thus, a class has
我正在试验专门的析构函数。这段代码完全有效并且编译得很好: #include using namespace std; template class Cat { public: ~Cat(
所以我正在尝试制作一个递归链表。它看起来有点像这样: class List { int cur; //For now List* nxt; public: List()
我的代码如下: class TimeManager { public: virtual ~TimeManager(); }; class UserManager : virtual public T
我是一名优秀的程序员,十分优秀!