我有一个功能,我希望在90%的时间内完成清理操作,但在10%中我想要完成其他一些操作。
是否有某种方法可以使用像shared_ptr<>
这样的标准范围控件,以便最初可以有一个删除操作,然后在函数中可以更改删除操作?
shared_ptr<T> ptr( new T, std::mem_fun_ref(&T::deleteMe) );
ptr.pn.d = std::mem_fun_ref(&T::queueMe);
答案 0 :(得分:2)
创建shared_ptr
后,我认为您无法更改删除。
但你为什么要那样做?通常,当您创建对象时,您立即知道它必须如何被销毁。这不太可能改变。
如果你真的必须做一些特定的治疗,你仍然可以提供一个自定义删除器,根据所需的逻辑做特殊事情。
答案 1 :(得分:2)
有正当理由需要更改删除器。以此为例:
val1=2
val2=1
wb = load_workbook(os.path.abspath(os.path.join(os.path.dirname(__file__),'c:\ExcelData\pyExcel.xlsx')))
sheet = wb.get_sheet_by_name('Sheet1')
c = sheet.cell(row=val1, column=val2).value
d = sheet.cell(row=val2, column=val2).value
print(c)
print(d)
在这种情况下,foo()函数使用一些特殊的分配器来分配double *。它还需要以特殊方式释放内存。调用者不应该知道如何释放内存。
答案 2 :(得分:2)
并非如此-shared_ptr
的标准是以这样的方式编写的:Deleter
可以按值存储在控制节点中(一个特殊的对象,该对象包含引用计数器,保存删除器,跟踪弱指针等)。删除程序已被类型擦除,但是如果您以某种方式知道具体的删除程序类型,则可以使用std::get_deleter<Deleter, T>(T)
。使用它,您可以访问删除器并更改其状态。示例:
struct A {};
struct deleter {
void operator()(A* a) {delete a; }
int m_state;
};
std::shared_ptr<A> ptr(new A(), deleter{});
std::get_deleter<deleter>(ptr)->m_state = 5;
如果仅对所有删除器使用函数指针,则可以完全替换它,因为所有潜在的删除器都使用相同的签名。
(是的,我知道这个问题已有9年历史了,但是我只是在2020年遇到了这个问题,就这样解决了。它的可能原因是包装了C指针和旧代码中的对象,这些代码和对象通过原始指针管理所有权) )
答案 3 :(得分:1)
#include <iostream>
#include <memory>
#include <functional>
struct A {
~A() {
std::cout << "~A()" << std::endl;
}
};
using DeleterCb = std::function<void(A* p)>;
struct ADeleter {
public:
explicit ADeleter(DeleterCb cb) :
mDeleterCb(cb) {}
ADeleter() = delete;
~ADeleter() = default;
void operator()(A *a) {
mDeleterCb(a);
}
void setDeleterCb(DeleterCb cb) {
mDeleterCb = cb;
}
private:
DeleterCb mDeleterCb;
};
int main() {
auto sp = std::shared_ptr<A>(new A{},
ADeleter([](A *p){
delete p;
std::cout << "deleter_1" << std::endl;
})
);
std::get_deleter<ADeleter>(sp)->setDeleterCb(
[](A *p){
delete p;
std::cout << "deleter_2" << std::endl;
}
);
}
答案 4 :(得分:0)
这没有任何意义,因为有shared_ptr
个任意数量的shared_ptr
来管理价值的所有权。你需要全部修改它们,这是不可行的。我们不要忘记控制块是一个实现细节,所以去“aha,但在控制块中更改它”将不起作用。
删除操作应由class C {
...
void (C::action*)() { &C::action1 };
void action1();
void action2();
~C() { (this->*action)(); }
};
void test() {
std::shared_ptr<C> a;
a->action = &C::action2;
// action2 gets invoked once `a` falls out of scope
}
拥有的实例控制,例如
if [ -z $SSH_AUTH_SOCK ]; then
if [ -r ~/.ssh/env ]; then
source ~/.ssh/env
if [ `ps -p $SSH_AGENT_PID | wc -l` = 1 ]; then
rm ~/.ssh/env
unset SSH_AUTH_SOCK
fi
fi
fi
if [ -z $SSH_AUTH_SOCK ]; then
ssh-agent -s | sed 's/^echo/#echo/'> ~/.ssh/env
chmod 600 ~/.ssh/env
source ~/.ssh/env > /dev/null 2>&1
fi