gpt4 book ai didi

c++ - "immutable"具有非平凡构造函数的结构

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:25 32 4
gpt4 key购买 nike

我一直在寻找一种方法来声明某种具有非平凡构造函数的不可变类型。我目前的目标是从文件中读取数据来构造一个对象,以便以后不能修改它。它类似于 POD 类型,只是我需要来自文件的数据,因此构造函数必须读取它。

通过我的研究和实验,我想到了三种方法来做到这一点。基本上,我的问题是:有没有更好的方法来做我想做的事?

在下面的示例代码中,我将使用 std::cin 作为文件的替代品。首先,这是明显的 class-with-getters 方式:

class A {
public:
A() { std::cin >> m_i; }
int i() { return m_i; }

private:
int m_i;
};

事实上,我在使用这个解决方案时遇到了麻烦,仅仅是因为 getter(s)。毕竟,它是一种 POD 类型,我希望它被这样对待,具有公共(public)数据成员。另外,我只是不喜欢 setter/getter 。所以我尝试了一些 const-ness 并通过调整构造函数:

struct B {
B() : B(B::fromFile()) {
}

B(int i) : i(i) {
}

const int i;

private:
static B fromFile() {
int i;
std::cin >> i;
return B(i);
}
};

这里有几个问题。我需要委托(delegate)给一个静态方法,因为我无法直接在构造函数的初始化列表中获取成员的值。此方法需要为每个成员(这里只是i)创建一个拷贝,并分别初始化它们,以便在使用复制构造函数最终构造初始对象之前将它们传递给另一个构造函数。此外,由于新的构造函数和静态方法,它需要更多的代码行。

因此,这种方法似乎注定要失败。然后我意识到,我真正想要的是该类/结构的每个实例都是 const。但是,据我所知,没有办法强制用户每次都使用 const 关键字。因此,我想到了使用 别名声明。有点像标准库为 const_reference 等所做的(几乎在每个容器中)。只有在这种情况下,它会是另一种方式:类型将被称为 NonConstType,或者我们说 MutableType,并且别名将像这样声明:

using Type = const MutableType;

因为我不想污染命名空间,所以让我们使用一个 Mutable 命名空间。代码如下所示:

namespace Mutable {
struct C {
C() { std::cin >> i; }

int i;
};
}

using C = const Mutable::C;

通过这种方式,我可以提供一个“不可变”类,它像 C 结构(没有 getter)一样处理,但仍然可以用来自不同文件的数据来构造。此外,可变版本仍然可用,我认为这毕竟是一件好事。

那么,还有别的办法吗?在这三种代码中,是否有我没有考虑到的优点或缺点?

A full testing code can be found here.

最佳答案

您正在使用 C++11,那么为什么不使用聚合初始化?

#include <iostream>

struct Foo {
const int val; // Intentionally uninitialized.
};

struct Foo create_foo_from_stream (std::istream& stream) {
int val;
stream >> val;
return Foo{val};
}

int main () {
Foo foo (create_foo_from_stream(std::cin));
std::cout << foo.val << '\n';
}

初始化 struct Foo 的唯一方法是通过聚合初始化或复制构造。默认构造函数被隐式删除。

请注意,在 C++14 中,您可以使用默认成员初始化程序并仍然使用聚合初始化:

#include <iostream>

struct Foo {
const int val = 0; // Prevents aggregate in C++11, but not in C++14.
};

struct Foo create_foo_from_stream (std::istream& stream) {
int val;
stream >> val;
return Foo{val};
}

int main () {
Foo foo (create_foo_from_stream(std::cin));
Foo bar; // Valid in C++14.
std::cout << foo.val << bar.val << '\n';
}

关于c++ - "immutable"具有非平凡构造函数的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37727867/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com