【问题标题】:C++ class construction by member initializer list with pointer to member addressC++ 类构造由成员初始化器列表和指向成员地址的指针
【发布时间】:2020-12-21 13:59:04
【问题描述】:

我有一个基于 C 的库(准确地说是 Vulkan),它通过将它们的地址作为参数传递给库函数来初始化和设置值。为了防止任何泄漏并确保调用清理(即使某处发生异常),我想将该值封装在一个 RAII 类中,该类为其调用 createdestroy 库函数:

value_t value; // value must live somewhere else
library_create_value( value_t* value );
library_destroy_value( value_t value ); // must not be forgotten to call at the end

C 程序在这里正常工作不会有任何问题:

int main() {
  value_t myValue;                // fine, myValue lives on the stack of main()
  library_create_value( &value ); // and is ready to be used now

  // do all work, use myValue

  library_destroy_value( value ); // the required clean up
  return 0;
}

但现在编写 C++ RAII 包装器,我很难找到初始化 value 的最佳解决方案,就像我通常做的那样:

class RAII_wrapper {
  value_t myValue;

public:
  RAII_wrapper() : 
    myValue( library_create_value() ) // doesn't work here as it would normally do!
  {} 

  ~RAII_wrapper() {
    library_destroy_value( value );   // nothing special here
  }

  // other methods to use myValue would be here
}

当然,我可以在构造函数本身中进行创建调用,直到那时 myValue 未初始化 - 但那是(在某处称为)“没有好的风格”。

这个任务的(官方)最佳解决方案是什么?

【问题讨论】:

  • 如果您不想使用您已经使用的解决方案(在构造函数的主体中调用library_create_value())的唯一原因是因为您担心它“没有好的风格”那么您可以尝试在CodeReview.SE 上使用您的工作代码来询问这个问题。 StackOverflow 上的“好风格”主要是基于意见的

标签: c++ raii legacy-code


【解决方案1】:

听起来您希望在堆上包装一个对象的指针,即使这不是您提供的 main() 中的用法。一个小的更改将允许这样做,同时还确保您只创建一次对象。第一个示例看起来您可以构造对象两次,一次使用默认构造函数,另一次修改它。请参见下面的示例:

class RAII_wrapper{
    private:
        value_t *myValue; // This maintains same function call as example
    public:
        RAII_wrapper(){
            library_create_value(myValue); 
        }
        ~RAII_wrapper(){
            library_destroy_value(myValue); 
        }
};

编辑:如果这不是 C 库,您可以使用智能指针而不是原始指针来至少避免 library_destroy_value() 调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多