gpt4 book ai didi

c++ - 构造函数初始化列表与昂贵的操作

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

考虑一个假设场景,其中两个类可以默认构造或相互构造,但任何一种方式都被认为是昂贵的(故意设计的示例如下):

struct PrivateKey;

struct PublicKey {
PublicKey(); // generate a random public key (1 minute)
PublicKey(const PrivateKey& b); // find a public key corresponding to a private key (1 year)
...members...
};

struct PrivateKey {
PrivateKey(); // generate a random private key (1 minute)
PrivateKey(const PublicKey& a); // find a private key corresponding to a public key (1 year)
...members...
};

(这当然可以浓缩为一类,但问题的有效性不受影响。假设为了连贯性,两者之间没有对称性。)

现在有一个结构包含两者的实例并且需要这种交叉初始化。然而,我们可能需要两个方向,所以初始化列表不能真正削减它(它们不是按照列出的顺序运行,而是按照成员定义的顺序运行,这里不能固定顺序):

struct X {
PublicKey a;
PrivateKey b;
X(int): a(), b(a) { }
X(float): b(), a(b) { } // UB: a(b) happens before b is initialized
};

当然可以试试:

struct X {
PublicKey a;
PrivateKey b;
X(int): a(), b(a) { }
X(float): a(), b() { a = PublicKey(b); }
};

但这有多个问题,其中X 的第二个构造函数中运行 PublicKey 的昂贵的默认构造只是为了抛出结果马上就是第一个。 PublicKey::PublicKey() 可能有副作用。两者仍然可以通过创建一个只暴露给 friend X 的廉价私有(private)构造函数来缓解,这将使该类处于某种虚拟状态,但引入一些引用或常量成员并且 该类可能不会可移动分配或可交换,禁止对X::X(float) 的主体进行任何更改。有更好的模式可以遵循吗?

最佳答案

通过使用指向包含类的指针,而不是直接嵌入包含类,并在构造函数体内自己构造包含对象,可以避免构造顺序问题。

struct X {
std::unique_ptr<PublicKey> a;
std::unique_ptr<PrivateKey> b;
X(int) {
a = std::make_unique<PublicKey>();
b = std::make_unique<PrivateKey>(*a);
}
X(float) {
b = std::make_unique<PrivateKey>();
a = std::make_unique<PublicKey>(*b);
}
};

关于c++ - 构造函数初始化列表与昂贵的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40138017/

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