0

我在一个类中有一个可选成员,我想通过一个方法按值返回。示例代码:

#include <stdio.h>
#include <optional>
#include <iostream>
using namespace std;

class bar {
public:
    int a;

    bar(const bar &obj) {
        a = obj.a;
    }
};

class foo {
public:
    void init(){
        abc->a = 100;
    }

    optional<bar> get() {
        return abc;
    }
    
    optional<bar> abc;
};

int main()
{
    foo temp;
    temp.init();
    auto copied = temp.get();
    cout << "Expected value is 100, got: " << copied->a;
    return 0;
}

该代码输出一些垃圾值。

我怎样才能做到这一点?


根据我的理解, optional 为底层类型(不仅仅是一个引用)存储了一个完全分配的内存,并且在返回一个可选变量时,底层类型的复制构造函数应该启动,它应该将内存原样复制到新的返回的可选值。

4

2 回答 2

4

您需要使用构造函数optional来确保它包含一个对象:(假设bar删除了阻止构造它的冗余复制构造函数)

foo()
    : abc{bar{100}}
{
}

或者,在optional创建之后:

void init(){
    abc = bar{100};
}

否则,将optional保持为空状态,并且->在空上调用optional会导致未定义的行为。当源为空时,的复制构造函数optional不会复制构造包含的对象。

于 2020-09-10T07:46:55.780 回答
1

std::optional就像一个智能指针,它默认为“null”值,因此访问其成员将是未定义的行为。您需要在使用前对其进行初始化:

void init(){
  abc = bar();
  abc->a = 100;
}

请注意,除了通过复制构造函数之外,它bar是不可构造的,因此您需要添加默认构造函数或带有int参数的构造函数或删除不必要的复制构造函数。

于 2020-09-10T07:47:55.847 回答