适当的方法将unique_ptr初始化为类成员包装C' structs'
我正在尝试在C ++程序中实现一些OPENSL功能。 OPENSL库需要大量的内存分配 / DealLocation。我的方法是将所需的结构从OpenSL打包到类中,并用构造函数分配内存,并通过驱动器对其进行处理。
现在,我想采用另一种方法,其中每个成员都被代表为带有DELERE的独特指针。这意味着我不必依靠对象的破坏者来释放内存。
假设我的班级看起来像这样:
class OpensslSignature {
public:
OpensslSignature() = default;
std::unique_ptr<X509, decltype(X509_free) *> cert{nullptr, X509_free};
std::unique_ptr<EVP_PKEY, decltype(EVP_PKEY_free) *> pkey{nullptr, EVP_PKEY_free};
void readCert(const std::string &name);
void readKey(const std::string &key);
}
实现是这样的:
void OpensslSignature::readCert(const std::string &name) {
BIO *tmp = BIO_new_file(name.c_str(), "r");
cert = std::unique_ptr<X509, decltype(X509_free) *>(PEM_read_bio_X509(tmp, NULL, 0, NULL), X509_free);
BIO_free(tmp);
if (!cert) {
// error handling
}
}
void OpensslSignature::readKey(const std::string &key) {
// similiar to readCert
}
初始化这样的unique_ptr是正确的吗?我应该将它们设置为标题中的nullptr吗?还是将它们初始化为构造函数会更好?
同样,当初始化readcert()函数中的指针时,我是否真的需要再次编写整个指针定义std :: simelod_ptr&type,dece,deleter&gt;()
?
还是使用std :: make_unique()初始化更好?
I'm trying to implement some openssl functionality in a C++ program. The openssl library requires a lot of memory allocation / deallocation. My approach is to pack the required structs from openssl into a class and allocate the memory with the constructor and deallocate it via the destructor.
Now I wanted to move to a different approach where each member is represented as a unique pointer with a deleter. This would mean that I would not have to rely on the destructor of the object to release the memory.
Let's say my class looks like this:
class OpensslSignature {
public:
OpensslSignature() = default;
std::unique_ptr<X509, decltype(X509_free) *> cert{nullptr, X509_free};
std::unique_ptr<EVP_PKEY, decltype(EVP_PKEY_free) *> pkey{nullptr, EVP_PKEY_free};
void readCert(const std::string &name);
void readKey(const std::string &key);
}
The implementation is like this:
void OpensslSignature::readCert(const std::string &name) {
BIO *tmp = BIO_new_file(name.c_str(), "r");
cert = std::unique_ptr<X509, decltype(X509_free) *>(PEM_read_bio_X509(tmp, NULL, 0, NULL), X509_free);
BIO_free(tmp);
if (!cert) {
// error handling
}
}
void OpensslSignature::readKey(const std::string &key) {
// similiar to readCert
}
Is it correct to initialize unique_ptrs like this? Am I supposed to set them to nullptr in the header? Or would it be better to initialize them in a constructor?
Also when initializing the pointer in the readCert() function, do I really need to write the entire pointer definition again std::unique_ptr<type, deleter>()
?
Or is it better to initialize with std::make_unique()?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的一般C ++原理是RAII-资源采集是初始化。在线搜索该术语非常容易。
这也意味着初始化是资源获取。通常不应将对象初始化为某些无法使用的空状态,然后您需要调用另一个功能来完成实际工作。
在这种情况下,看起来
opensslSignature
有两个部分,这两个部分都应该是本身。x509_free
应从某种cert-type的灾难中调用,而evp_pkey_free
应从某种“ keypair”类型的销售器中调用。OpenSlSignature
构造函数然后可以采用这两种类型,您将不再需要ReadCert
函数。如果愿意,您可以在两个实现中使用
unique_ptr
。我不确定这是否完全是最简单的路线,但这是一件小事。无论如何,您都会将其制作私有
,如果您以后更改实现该类别的代码无关紧要。The general C++ principle here is RAII - Resource Acquisition Is Initialization. It's quite easy to search for that term online.
It also means that Initialization Is Resource Acquisition. Objects generally shouldn't be initialized to some unusable, empty state, where you then need to call another function to do the real work.
In this case, it looks like
OpensslSignature
has two parts, both of which should be classes in their own right.X509_free
should be called from the destructor of some kind of Cert-type, whileEVP_PKEY_free
should be called from the destructor of some kind of "KeyPair" type.The
OpensslSignature
constructor can then take those two types, and you won't need areadCert
function anymore.You can use a
unique_ptr
in both of the implementations, if you like. I'm not sure if that's exactly the easiest route, but that's a small matter. You'd make itprivate
anyway, and if you later change the implementation that won't matter to code outside that class.