1

我有一个类,比如 C,其中一个成员数据,比如 X,取决于用户输入。每次运行时用户输入可能不同,在我当前的设计中,我的类的所有实例都存储对同一个对象 X 的引用。

我如何调整设计以使其允许不带参数的默认构造函数?

这样我可以使用复制赋值/复制构造函数,制作 C 数组,使用临时右值等。

以下是说明我的问题的最小工作示例。在我使用的情况下,Tag 指的是一些外部资源。

#include <iostream>
#include <string>
#include <vector>
#include <cassert>

using namespace std;

struct Tag {
    int N;
    string tag;
};

template<typename T>
struct Vec {
    const Tag& tag;
    T* vec;

    Vec(const Tag& tag_) : tag(tag_) {
        vec = new T[tag.N];
    }

    ~Vec() {
        delete [] vec;
    }
};

Tag make_tag(vector<string>& args) {
    assert(args.size() == 3);
    int N = stoi(args[1]);
    return Tag {N, args[2]};
}

vector<string> arguments(int argc, char* argv[]) {
    vector<string> res;
    for(int i = 0; i < argc; i++)
        res.push_back(argv[i]);
    return res; 
}

int main(int argc, char* argv[]) {
    vector<string> args = arguments(argc, argv);
    Tag tag0 = make_tag(args);
    Tag tag1;
    Vec<double> vec(tag0);
    return 0;
}
4

1 回答 1

1

我如何调整设计以使其允许不带参数的默认构造函数?

好吧,我建议三个选项:

  • 花哨的方式:使用std::optional<std::reference_wrapper<T>>会员。std::reference_wrapper用于将参考放在您不确定参考是否可以按原样工作的地方。std::optional<T>持有 aT或 a nullopt(即无值)。这具有无optional参数的默认初始值设定项的好处,因此您可以为 C 的无参数情况使用默认构造函数。

  • 老派方式:使用普通指针成员而不是引用。将其初始化为nullptr无参数构造。(@RemyLebeau 也在评论中提出了这个建议。)

  • smart-ass RAII 方法Cstd::optional<C>. 这意味着无参数构造实际上并不构造 C - 它只是保留 a nullopt,将实际构造延迟到以后。当您必须C在其存在期间保持持有资源的不变性时,此解决方案是相关的;它还具有保留Cas的引用成员的好处const

我故意不考虑您的 MWE(您说这只是说明性的),并提供了更一般的答案。

于 2018-10-26T22:47:04.053 回答