简体   繁体   English

在初始化列表中使用复杂函数来初始化const成员一个好的设计?

[英]Is using a complex function in initializer list to initialize const member a good design?

recently I was looking at old horrible mess of a class... Long story short it would help with thread safety if one member was const. 最近我看着一个班级的老混乱...长话短说,如果一个成员是常设,它将有助于线程安全。
But the problem is that member is initialized in ctor, and it is nontrivial construction. 但问题是成员是在ctor中初始化的,而且是非常重要的构造。 So I was thinking about creating a special init function for that member. 所以我在考虑为该成员创建一个特殊的init函数。 Is that a good decision. 这是一个很好的决定。 Small super simple example(real code is full of conditionals :) and try-s) : 小超级简单的例子(真正的代码充满了条件:)和try-s):

class ComplexInitList
{
std::pair<double,double> init_pair(const int first, const int second)
{
    if ((first == 0) || (second == 0))
       throw std::invalid_argument("div by 0");
    return std::make_pair(1.0/first, 1.0/second);
}
const std::pair<double,double> p;
public:
 ComplexInitList(int a, int b):p(init_pair(a,b))
{
    std::cout << p.first << ", " << p.second << std::endl;
}  
};

This is actually a common and accepted solution to this problem. 这实际上是解决此问题的常见解决方案。 If possible, consider making the init function static, so that unexpected semantics of operations on object under construction (such as behaviour of virtual calls) can't kick in. 如果可能,请考虑使init函数保持静态,以便对正在构造的对象(例如虚拟调用的行为)的操作的意外语义无法启动。

Late to the party, but to add for any new search-engine'ers: 晚会,但添加任何新的搜索引擎:

If init_pair isn't going to be used anywhere else I find a lambda to be the most elegant way of solving this problem: 如果init_pair不会在其他地方使用,我发现lambda是解决这个问题的最优雅的方法:

class ComplexInitList
{
const std::pair<double,double> p;

public:
 ComplexInitList(const int a, const int b) : 
    p([](const int a, const int b) {
        if ((first == 0) || (second == 0)) {
            throw std::invalid_argument("div by 0");
        }

        return std::make_pair(1.0/first, 1.0/second);
    }()) // <-- Note the extra '()' with immediately calls the lambda!
{
    std::cout << p.first << ", " << p.second << std::endl;
} 

};

To initialize a const data member the only way is to initialize it in member initializer list . 要初始化const数据成员,唯一的方法是在member initializer list初始化它。

p is a const, so it can be initialized to a value, but it can't be assigned a value. p是一个const,因此可以将其初始化为一个值,但不能为其赋值。 Conceptually, calling a constructor creates an object before the code within the brackets is executed. 从概念上讲,调用构造函数会在执行括号内的代码之前创建一个对象。 Thus calling ComplexInitList(int a, int b):p(init_pair(a,b)) cause the program first to allocate space for member p . 因此, calling ComplexInitList(int a, int b):p(init_pair(a,b))会导致程序首先为成员p分配空间。

Then program flow enters the brackets and uses ordinary assignment to place values into the allocated space. 然后程序流进入括号并使用普通赋值将值放入分配的空间。 So if you want to initialize a const data member, you have to initialize it in member initializer list 因此,如果要初始化const数据成员,则必须在member initializer list初始化它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用静态成员函数初始化初始化列表中的常量成员变量是否有任何问题? - Are there any problems in using a Static Member Function to initialize a Constant Member Variable in an Initializer List? 使用在初始化列表中早先初始化的成员初始化成员是否安全? - Is it safe to initialize a member using a member initialized earlier in initializer list? 使用const初始化列表初始化const向量 - initialize const vector with const initializer list 如何在 C++ 初始值设定项列表中将常量引用成员初始化为另一个成员(标准向量) - How to initialize a const reference member to another member (std vector) in C++ initializer list 成员初始化列表:从返回元组的函数初始化两个成员 - Member initializer list: initialize two members from a function returning a tuple 初始化包含带有初始化列表的const数组的Struct - Initialize a Struct containing a const array with initializer list 使用C ++类中的复杂函数初始化const成员 - Initialize const members using complex function in C++ class 使用初始化列表在构造函数中初始化复杂的 map - Initialize complex map in constructor with initializer list 初始化列表中const引用成员的初始化 - Initialization of const reference member in initializer list 在类的成员初始化器列表中初始化std :: tuple - Initialize std::tuple in member initializer list of a class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM