在析构函数中为单状态 classes/static 成员管理资源在 C++ 中是个坏主意吗?
Is managing resources in destructor for monostate classes/static members a bad idea in C++?
我正在尝试实现管理一些 std::thread 的单态 class。线程 运行 直到标志变为等于 false。标志更改为 false 后 - 线程停止。但看起来我必须明确地调用停止方法。在析构函数中调用它会给我带来运行时错误(在 GCC 4.8 for ARM、GCC 4.9 for x86_64 和 MSVC 2017 上测试)。
我说得对吗,这种行为是由于
"Static members of a class are not associated with the objects of the
class: they are independent objects with static storage duration or
regular functions defined in namespace scope, only once in the
program."
所以析构函数调用被省略了?
代码示例:
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
void runThread(const std::atomic<bool> &_isRunning) {
while (_isRunning) {
std::cout << "Me running.." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(30));
}
}
class test {
static std::thread thread;
static std::atomic<bool> isRunning;
public:
test();
~test();
static void go();
static void stop();
};
std::thread test::thread;
std::atomic<bool> test::isRunning{ false };
test::test() {}
void test::go() {
isRunning = true;
thread = std::thread(runThread, std::ref(isRunning));
}
void test::stop() {
isRunning = false;
if (thread.joinable()) {
thread.join();
}
}
test::~test() {
stop();
}
int main() {
test::go();
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "Done here!!!!!!!!!!!!!!!!!";
// Will not crash anymore if uncomment
//test::stop();
return 0;
}
使用 std::async 和 std::feature 得到相同的结果但没有错误。线程只保留 运行.
P.S.
使 class 非单态解决了运行时错误,但给我留下了这个问题。管理资源对于单态 classes/static 成员来说是一种不好的做法吗?
~test();
应该在销毁任何 "test" 对象之前调用。您没有在代码中创建 "test" 个对象,所以您是对的,
Static members of a class are not associated with the objects of the
class: they are independent objects with static storage duration or
regular functions defined in namespace scope, only once in the
program.
静态对象的构造函数在之前main
被执行,析构函数在之后被调用main
已完成(通常来自 atexit
)。
在析构函数中打个断点,很容易看出来
我正在尝试实现管理一些 std::thread 的单态 class。线程 运行 直到标志变为等于 false。标志更改为 false 后 - 线程停止。但看起来我必须明确地调用停止方法。在析构函数中调用它会给我带来运行时错误(在 GCC 4.8 for ARM、GCC 4.9 for x86_64 和 MSVC 2017 上测试)。 我说得对吗,这种行为是由于
"Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program."
所以析构函数调用被省略了?
代码示例:
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
void runThread(const std::atomic<bool> &_isRunning) {
while (_isRunning) {
std::cout << "Me running.." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(30));
}
}
class test {
static std::thread thread;
static std::atomic<bool> isRunning;
public:
test();
~test();
static void go();
static void stop();
};
std::thread test::thread;
std::atomic<bool> test::isRunning{ false };
test::test() {}
void test::go() {
isRunning = true;
thread = std::thread(runThread, std::ref(isRunning));
}
void test::stop() {
isRunning = false;
if (thread.joinable()) {
thread.join();
}
}
test::~test() {
stop();
}
int main() {
test::go();
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "Done here!!!!!!!!!!!!!!!!!";
// Will not crash anymore if uncomment
//test::stop();
return 0;
}
使用 std::async 和 std::feature 得到相同的结果但没有错误。线程只保留 运行.
P.S.
使 class 非单态解决了运行时错误,但给我留下了这个问题。管理资源对于单态 classes/static 成员来说是一种不好的做法吗?
~test();
应该在销毁任何 "test" 对象之前调用。您没有在代码中创建 "test" 个对象,所以您是对的,
Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program.
静态对象的构造函数在之前main
被执行,析构函数在之后被调用main
已完成(通常来自 atexit
)。
在析构函数中打个断点,很容易看出来