【发布时间】:2019-03-27 16:50:22
【问题描述】:
简介
我们来介绍这个简单的例子:
#include <cmath>
class X
{
public: // Members
/// A ^ B + A
int A;
/// A ^ B + B
int B;
public: // Specials
X(
const int & A,
const int & B
)
: A(A)
, B(B)
{
const auto Pow = static_cast<int>(std::pow(A, B));
this->A += Pow;
this->B += Pow;
}
};
琐事
- 引入的类有两个成员变量:
A和B。 - 它们的值分别为
A ^ B + A和A ^ B + B。 - 它们都共享共同的复杂初始化代码(假设
std::pow是复杂的)。
问题
我想让A 和B 都成为const 成员。
问题
如何在不重复复杂初始化的情况下做到这一点(即避免两次调用std::pow)?
我尝试过的
#include <cmath>
class X
{
public: // Members
/// A ^ B + A
const int A;
/// A ^ B + B
const int B;
public: // Helpers
struct Init
{
public: // Members
int A;
int B;
public: // Specials
Init(
const int & A,
const int & B
)
: A(A)
, B(B)
{
const auto Pow = static_cast<int>(std::pow(A, B));
this->A += Pow;
this->B += Pow;
}
};
public: // Specials
X(
const Init& Init
)
: A(Init.A)
, B(Init.B)
{};
X(
const int & A,
const int & B
)
: X(Init(
A,
B
))
{};
};
- 创建
struct Init,该struct Init扮演类X的过去版本的角色。 - 使
X成为const成员,同时保持Init成员非const。 - 使用构造函数委托将构造函数参数重定向到
Init。 - 将非
const成员变量从Init移动到X并使其成为const。- 注意没有
std::move,因为int是TriviallyCopyable。
- 注意没有
但是,我的解决方案似乎过于复杂。任何帮助将不胜感激。
没有目标
- 创建另一个
X成员变量来存储公共代码结果(iestd::pow)。 - 在
X类之外添加另一个间接级别(例如为X引入基类)。
注意
解决方案可以使用比 C++11 更新的 C++ 版本。
【问题讨论】:
-
您是否考虑过将成员设为私有、非 const 并且只设为访问器?这是启用此类功能的正常方式。
-
我想使用
const,因为我将存储这些值直到程序退出(eg 好几个小时),而不是因为我不希望它们被编辑/visible,所以 getters/setters 不是我的目标。 -
变量的持续时间将是类实例的持续时间,无论它们是
const还是非const。你在想static吗? -
另外,您是否考虑过您可能没有启用 C++11?当我将
Init init(1,2); X x(init); std::cout << x.A << " " << x.B << std::endl;放在我的 main 中时,你的代码对我来说很好,输出是2 3。 -
我的代码中会有很多这个类的实例,所以
static不是一个选项。我的代码中有std::latest,它现在使用了许多 C++17 和一个 C++20 功能,所以我确实启用了 C++11。顺便说一句,我的问题已经解决了,谢谢。
标签: c++ constructor constants member-initialization