- 主题:C++如何在程序结束的时候不调用析构函数
这是一个挺有趣的问题。是这样的,在一个系统里,有一个函数,已经写好了
HigherLevel<Good> GetGood(std::string path);
这个函数根据一个文件的路径来做一个事情,比如,把这个文件读入,然后创建一个文件,把原来文件的内容翻转写入。然后,返回一个Good变量。这里,HigherLevel是另一个模板类,用来包装一下函数返回的正确或者错误等信息。所以关键是Good。Good这个类保存了一些这个新创建的文件的信息,它的析构函数把这个新创建的文件删除。
有一个单元测试,里面需要做这样的事情。因为主测试是Rust写的,而Rust会并行执行,那样就会造成每个测试生成了不同的新文件,但是这样就出现了一些问题。解决办法是,把创建这个唯一文件的过程放到另一个进程,可以只做一次。这个单独的进程,是用C++写的,就有人建议我直接用GetGood。我用了,发现了一个问题。在我这个测试里,是用了一个单独的进程来调用GetGood
int main(...){
auto a = GetGood(...);
return 0;
}
看起来不错?但是,进程结束的时候另一个主测试进程开始测试,发现需要的文件不在,因为a析构了。然后我就加入了等待
int main(...){
auto a = GetGood(...);
sleep(1000s);
return 0;
}
可以了?代码审查者不喜欢,说,你不能想个办法让析构函数不调用吗?我绞尽脑汁,另一个审查者想出了一个办法。然后我又想出了另一个。
看看大家有多少简单的办法?
--
FROM 98.42.143.*
看着都快被绕晕了。
你需要把问题最简化。
【 在 bihai (new half life) 的大作中提到: 】
: 这是一个挺有趣的问题。是这样的,在一个系统里,有一个函数,已经写好了
: HigherLevel<Good> GetGood(std::string path);
: 这个函数根据一个文件的路径来做一个事情,比如,把这个文件读入,然后创建一个文件,把原来文件的内容翻转写入。然后,返回一个Good变量。这里,HigherLevel是另一个模板类,用来包装一下函数返回的正确或者错误等信息。所以关键是Good。Good这个类保存了一些这个新创
: ...................
--
FROM 117.136.120.*
用指针就不会析构了吧。人为制造个可能会内存泄露的bug
【 在 bihai 的大作中提到: 】
: 这是一个挺有趣的问题。是这样的,在一个系统里,有一个函数,已经写好了
: HigherLevel<Good> GetGood(std::string path);
: 这个函数根据一个文件的路径来做一个事情,比如,把这个文件读入,然后创建一个文件,把原来文件的内容翻转写入。然后,返回一个Good变量。这里,HigherLevel是另一个模板类,用来包装一下函数返回的正确或者错误等信息。所以关键是Good。Good这个类保存了一些这个新创建的文件的信息,它的析构函数把这个新创建的文件删除。
: ...................
--
FROM 120.244.156.*
把a封装进一个union中即可。
union中成员都需要手工调用构造函数和析构函数,不会自动调用的。
【 在 bihai 的大作中提到: 】
: 这是一个挺有趣的问题。是这样的,在一个系统里,有一个函数,已经写好了
:
: HigherLevel<Good> GetGood(std::string path);
: ...................
--来自微水木3.5.11
--
FROM 140.206.195.*
天下本无事
--
FROM 101.88.154.*
弄个智能指针类,退出scope之前,可以detach()一下,放弃owner让其成为孤儿,就不调用析构了
--
FROM 114.241.228.*
好像是可以。但是既然原来就是这个类Good,要获得unique_ptr还得复制
unique_ptr<Good> g = unique_ptr<Good>(GetGood(...));
g.release();
不如
new Good(GetGood(..));
更直接
【 在 z16166 的大作中提到: 】
: 弄个智能指针类,退出scope之前,可以detach()一下,放弃owner让其成为孤儿,就不调用析构了
--
FROM 98.42.143.*
对,用指针就可以避免析构。sleep不会造成内存泄漏,但是审查代码的不让我sleep。他们居然建议有内存泄漏的办法。
【 在 dormouseBHU 的大作中提到: 】
: 用指针就不会析构了吧。人为制造个可能会内存泄露的bug
--
FROM 98.42.143.*
学了一招。有意思。这个和子类不同,子类一定会调用基类的析构。
下面说说审查者的建议
auto a = GetGood(...);
exit(0);// 栈上变量不析构
return 0; // 不会走到这一步
【 在 KillnCov 的大作中提到: 】
: 把a封装进一个union中即可。
: union中成员都需要手工调用构造函数和析构函数,不会自动调用的。
--
FROM 98.42.143.*
这个测试最开始的问题是Rust本身测试时多线程导致的。如果在Rust里面GetGood
Setup{
a = GetGood(...);
Ok(a);
}
Test_1{
let _tmp = Setup();
...
}
Test_2{
let _tmp = Setup();
...
}
问题是,每个Test创造了不同路径的资源,但是却因为测试的控制文件里是固定了第一个资源,比如叫resource-0;Test_1结束的时候,会释放这个资源0,Test_2创造了另一个资源文件,却通过控制文件去查找资源0,资源0可能不在(比如Test1结束了),也可能没创建完。最后,在大家的讨论后,决定,把创建唯一资源这个事情交给另一个进程去做。就是,Rust无法做Singleton,或者说我们这个项目里面无法简单的创造Rust的Singleton。
这个问题绕了一大圈,可能就没法简单描述。
【 在 javaboy 的大作中提到: 】
: 看着都快被绕晕了。
: 你需要把问题最简化。
:
{
--
FROM 98.42.143.*