是否有推荐的策略来处理期望手动管理原始指针的外部库。例如,一个采用指针向量的方法:
ALibraryFunc(std::vector<ALibraryData*> p);
所以通常你会用以下内容创建你的矢量:
std::vector<ALibraryData*> myVec;
for(...)
{
myVec.push_back(new ALibraryData(args));
}
//and then
ret = ALibraryFunc(myVec);
//and then
for(auto &a:myVec)
{
delete a;
}
myVec.clear();
我更喜欢使用智能指针,但图书馆不会接受它们。这让我想知道这样的事情是否比手动做得更臭:
std::vector<std::unique_ptr<ALibraryData>> myVecUP;
std::vector<ALibraryData*> myVec;
for(...)
{
myVecUP.push_back(std::make_unique<ALibraryData>(args));
myVec.push_back(myVecUP.back().get());
}
//and then
ret = ALibraryFunc(myVec);
myVec.clear();
myVecUP.clear();
第二个版本在异常或错误的情况下似乎更安全,但它确实存在悬挂指针的风险。我错过了一些明显的东西吗?你会做什么/你会做什么?
答案 0 :(得分:5)
你可以声明一个拥有原始指针向量的小类,并删除析构函数中的指针:
struct VecOwner {
std::vector<ALibraryData*> vec;
VecOwner(<some arguments>)
{
// fill the vector here
}
~VecOwner()
{
for(auto &a:vec)
delete a;
vec.clear();
}
};
您应该能够在使用该库的所有地方重用该类。
答案 1 :(得分:3)
您可以使用&#39;范围退出&#39;成语:
//open scope block
{
std::vector<ALibraryData*> myVec;
////////////////////////////////////////
struct MyVecRAIICleaner{
std::vector<ALibraryData*> * myVecPtr;
~MyVecRAIICleaner(){
if (myVecPtr) {
for(auto& a: *myVecPtr)
delete a;
myVecPtr->clear();
}
}
} myRAIICleaner = {&myVec};
////////////////////////////////////////
for(...)
{
myVec.push_back(new ALibraryData(args));
}
//and then
ret = ALibraryFunc(myVec);
/** You needn't below code. */
////and then
//for(auto &a:myVec)
//{
// delete a;
//}
//myVec.clear();
}// end scope block
编辑:
对不起,但是Wojtek Surowka的答案不是例外安全或者在构造函数中需要额外的try catch块。