【问题标题】:Getting out of a function, with reference, an object of a type with no default constructor离开一个函数,引用一个没有默认构造函数的类型的对象
【发布时间】:2013-02-06 21:33:45
【问题描述】:

例如

bool read(Input &input);

Input input; //error
bool success = read(input);

将是一个错误,因为 Input 没有默认构造函数。

在这种情况下,我可以使用任何技巧将 Input 对象从函数中取出吗?我想一定有一些 unique_ptr 技巧可供我使用,但我不确定具体如何。欢迎提出其他方法。

请举例说明读取函数的外观。

我宁愿不为此目的为 Input 创建一个(无意义的)默认构造函数,并注意这只是一个愚蠢的例子,所以不要对“Input”、“read”、等等:)

【问题讨论】:

  • read() 返回Inputthrow 失败时的异常?
  • 为什么不Input read();
  • 因为在我的情况下,返回类型很重要,甚至“false”也不足以成为异常。
  • 传递一个指向 Input 的指针
  • 使用Input 确实拥有的构造函数。

标签: c++ pointers c++11 unique-ptr


【解决方案1】:
bool read(unique_ptr<Input> &input)  // read asume input is disposable/empty
{    ....
  input.reset(new Input( a,d,c ) );
     ....
 }

....
unique_ptr<Input> input;      //error ?
bool success = read(input);
if (input)
  if (succes)
     input->X();
  else
     input->Y();

【讨论】:

  • 是的,我想像这样,但问题是您不能在读取函数中重新分配输入指针。我想我可以做“input.reset(new 不管)”,但这听起来对吗?
  • A unique_ptr 本身就足以发出“没有对象”的信号,所以我看不到通过引用传递它的目的 bool 函数结果。此外,相对于普通的 C++ 堆栈分配,动态分配效率极低。那么,对于这种冗长、晦涩和低效,有什么令人信服的论据呢?
  • @ 干杯和hth。 - Alf :这只是一个愚蠢的例子,所以不要对“输入”、“读取”等词附加任何特殊含义......因为在我的情况下,返回类型很重要,甚至是“假” " 不是无效的
【解决方案2】:
unique_ptr<Input> input_ptr = read();

其中read() 定义为:

unique_ptr<Input> read()
{
    .
    .
    .
    return unique_ptr<Input>(new Input(x,y,z));
}

【讨论】:

  • 一种更高效、更安全的变体是使用 Barton 和 Nackman 的 Fallible 类的实现,例如 boost::optional。对于 POD 内部类型,实现(在几分钟内)也很简单。我并没有在我的回答中暗示这一点——我只是说还有更多的可能性——因为显然 OP 正在学习 C++ 的基础知识。
【解决方案3】:

从 cmets 看来,您的问题是设计一个函数

  • 可能会失败(如果是这样,应该向调用者发出信号),

  • 但如果不是,则生成一个没有默认 cconstructor 的类型的值

第一点很简单:使用异常。

第二点也很简单:使用函数返回值特性。

即,

Object foo()
{
    if( "didna wrok" )
    {
        throw std::runtime_error( "foo: I failed, miserably" );
    }

    return Object( arg1, arg2, arg3 );
}

现在还有很多其他方法可以做到这一点,但上面是最自然的,直接使用旨在支持和完全解决这些方面的语言特性。

【讨论】:

    【解决方案4】:

    如果您处于 C+11 之前的世界,可以使用 malloc 解决方法:

    bool read(Input &input); // keep the function read intact 
    
    Input* input = static_cast<Input*>(malloc(sizeof(Input))); // bypass constructor
    bool success = read(*input);
    ...
    free(input); // don't forget to free input later
    

    【讨论】:

      猜你喜欢
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      相关资源
      最近更新 更多