gpt4 book ai didi

c++ - 使用可变参数模板来创建更安全的传递新对象的方法是个好主意吗

转载 作者:行者123 更新时间:2023-11-28 05:49:54 25 4
gpt4 key购买 nike

假设我有一个类,它有一个数据成员,它是指向抽象类 Foo 的指针。该类的 setter 之一,setFoo 请求指向 Foo 的子类之一的指针。程序员应该传递的是子类的新对象,如setFoo(new FooBar(5, 10));。因此,FooContainer 是唯一持有对象引用的对象,也是唯一负责删除该对象的对象。一个例子就像...

class FooContainer final {
public:
FooContainer() : currentFoo(nullptr) {}
~FooContainer() {
delete currentFoo;
}

//Setter
void setFoo(Foo *foo) {
if (currentFoo != nullptr)
delete currentFoo;

currentFoo = foo;
}

//test that it holds the class
void fireFoo() {
currentFoo->func();
}
private:
Foo* currentFoo;
};

这有一些很大的陷阱,比如我这样做。

int main() {

FooContainer fc1;
holder.setFoo(nullptr); //Error passing a null pointer
holder.fireFoo();

//---

FooContainer fc2;

Foo* fooBar = new FooBar(5, 10);
holder.setFoo(fooBar); //Error now two objects hold references to fooBar
holder.fireFoo();

delete fooBar; //Error

return 0;
}

我想出的解决方案是使用可变参数模板函数在传递 foo 子类类型和可变参数的地方设置 foo 来构造新的 Foo 子类,就像这样。

    template <typename T, typename... Args>  
void setFoo(Args... args) {
currentFoo = new T(std::forward<Args>(args)...);
};

所以现在我可以做 setFoo<FooBar>(5, 5);这确保 currentFoo 不是空指针并且 FooContainer 是唯一的引用持有者。这是解决这个问题的正确方法吗?我以前从未遇到过这样的问题,如果我出错了,我总是可以回退到唯一指针。

最佳答案

对于所有权,你应该使用一个智能指针

然后你可以使用 setter(它允许很容易地拥有多态的 Foo):

class FooContainer final {
public:
void setFoo(std::unique_ptr<Foo> foo) { // may be empty
currentFoo = std::move(foo);
}

void fireFoo() {
// may be empty if not set (constructor doesn't feed it) or set with nullptr
if (currentFoo) {
currentFoo->func();
}
}
private:
std::unique_ptr<Foo> currentFoo;
};

或内部工厂(确保您始终有值(value))

class FooContainer final {
public:
template <typename...Ts>
explicit FooContainer(Ts&&... args) {
currentFoo = std::make_unique<Foo>(std::forward<Ts>(args));
}

template <typename...Ts>
void createFoo(Ts&&... args) {
currentFoo = std::make_unique<Foo>(std::forward<Ts>(args));
}

void fireFoo() {
assert(currentFoo); // Cannot be nullptr (except after moved currently ;) )
currentFoo->func();
}
private:
// You may even use `Foo currentFoo;` (which some changes above) if relevant
// (think about copy/move)
std::unique_ptr<Foo> currentFoo;
};

关于c++ - 使用可变参数模板来创建更安全的传递新对象的方法是个好主意吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35468927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com