适当的方法将unique_ptr初始化为类成员包装C' structs'

发布于 2025-01-29 04:48:37 字数 1190 浏览 4 评论 0原文

我正在尝试在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉风有信 2025-02-05 04:48:37

这里的一般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, while EVP_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 a readCert 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 it private anyway, and if you later change the implementation that won't matter to code outside that class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文