传递unique_ptr至函数遇作用域问题及删除函数报错求助
解决unique_ptr传递函数时的拷贝与作用域问题
嘿,我来帮你搞定这个问题!你遇到的两个问题其实是关联的,都是因为unique_ptr的独占所有权特性导致的:
为什么会报错?
unique_ptr设计的核心就是保证同一时间只有一个智能指针持有对象的所有权,所以它直接禁用了拷贝构造函数和拷贝赋值运算符——也就是编译器报错里的“deleted function”。你之前按值传递unique_ptr<binaryBase> answered,函数调用时会尝试拷贝这个智能指针,这刚好触发了被禁用的拷贝操作,自然就报错了。
作用域失效的原因
就算没报错,按值传递unique_ptr会把对象的所有权转移到函数内部,等askQuestion执行完毕,函数里的answered会被销毁,它指向的binaryBase对象也会被自动释放。这时候原来调用处的unique_ptr就变成空指针了,后续再用它自然就会出现作用域失效的问题。
正确的解决方案
根据你的代码场景,askQuestion只是需要修改binaryBase对象的位状态,不需要接管对象的所有权,所以用引用传递是最适合的方式:
修改后的askQuestion函数:
char askQuestion(string *questions[8], unique_ptr<binaryBase>& answered) { bool asked = false; char input = '0'; while (!asked) { int randomQuestion = (rand() % 8); // 记得初始化随机种子:srand(time(nullptr)) if (!(answered->getBit(randomQuestion))) { getInput(input, *questions[randomQuestion]); answered->toggleBit(randomQuestion); asked = true; } } return input; }
只需要在参数里加个&,把值传递改成引用传递:
- 这样不会触发
unique_ptr的拷贝操作,彻底解决那个删除函数的报错; - 所有权依然保留在调用者手里,函数执行完后,原
unique_ptr依然有效,不会出现作用域失效的问题; - 函数依然可以正常修改
binaryBase对象的内容(比如调用toggleBit)。
额外提醒
如果你以后遇到需要转移unique_ptr所有权的场景(比如函数要长期持有这个对象),可以用std::move来传递:
// 调用时转移所有权 auto myPtr = make_unique<binaryBase>(); char ans = askQuestion(questions, std::move(myPtr)); // 注意:此时myPtr已经是空指针,不能再使用它了
但这个场景显然不适合你的代码,因为后面的checkAnswer还需要用到这个binaryBase对象,所以引用传递才是正确选择。
内容的提问来源于stack exchange,提问作者Pat H.
相关产品推荐
相关产品推荐

