Raf*_*llo 2 c++ constructor pointers constants ctor-initializer
现代 C++ 中是否有一种方法可以在从访问指针参数派生的类中初始化 const 值?并且该指针可能为空,所以基本上在检查指针之后?
例如
// Dummy class to pass as argument in Class A through a pointer, just for this given example
class Zero
{
public:
int i = 0;
};
class A
{
public:
A(Zero* z) : isZero(z->i == 0) // in this simple e.g.
// could be: isZero(z == nullptr ? false : z->i), but immagine having a more complex structure instead,
// this kind of verbose way will work,
// but i am asking if something is already designed to deal with this kind of situation
{
// But here i can check the eventual nullpointer (or empty reference, or whatever other smart pointers
if (z==nullptr)
isZero=false; // or true or throw or whatever... but anyway can't be assigned here
}
const bool isZero;
};
Run Code Online (Sandbox Code Playgroud)
笔记:
如果不是指针,则可以是引用或智能指针,但在语义和语法上我认为是等效的,并且我认为不可能在 C++ 中表达这种意图(至少)
笔记2:
如果错过阅读注释,另一种解决方法可能是初始化程序列表中的一种z==nullptr ? false : z->i,但它仍然感觉很老套,基于这种模式的复杂场景将非常冗长并且可能容易出错,而不是只检查if z==nullptr一次,只是专门询问是否有事处理比较顺利
聚苯乙烯
我并不是要求删除 const 关键字,因为它是一种解决方法,或者任何使它起作用的方法。我确切地问是否有一种方法可以在 C++ 中覆盖上面的例如场景,或者是否甚至考虑它而不是找到解决方法,例如删除 const 或对初始化列表中的每个 const 变量进行检查。或者甚至存储参数的指针,然后每次检查它,或者甚至传递 const bool 作为参数,所有这些都可以工作,但实际上我是在问是否有适合这种情况的东西,最终如果不是为什么
正如你所说,在A(Zero* z) : isZero(z->i == 0)初始化的情况下isZero非常简单,它可以是单个表达式。如果不是那么简单,您可以使用 IILE 或简单地使用私有成员函数。
此 C++11 解决方案不需要您定义任何新符号,因此它可以说是最好且最少的方法。然而,由于可读性,有些人可能不喜欢它。
A(Zero* z) : isZero([z] {
// lots and lots of complicated decision making ...
return true; // or return something else
}()) /* empty constructor body: */ {}
Run Code Online (Sandbox Code Playgroud)
或者,您可以定义一个包含所有复杂逻辑的(静态)成员函数。
private:
static bool initIsZero(Zero* z);
public:
A(Zero* z) : isZero(initIsZero(z)) {}
Run Code Online (Sandbox Code Playgroud)
也可以调用成员初始值设定项列表中的非静态成员函数,但是,这是非常危险的,因为并非每个子对象都已初始化。您必须非常小心,不要在该上下文中调用依赖于尚未初始化的成员的成员函数。请参阅调用成员初始值设定项列表中的函数是否有问题?
const成员和后期初始化的一般说明您说过您不想将其删除const作为解决方法。虽然这是有道理的,但您应该仔细考虑是否真的需要const成员,因为它们使包含的类不可分配。
此外,无论数据成员是否存在,都应该使用上述解决方案之一const。在构造函数体内,不进行初始化;只有作业可以。对于普通类型,区别并不重要,除非它们是const,但无论如何,通常最好不要通过赋值来“延迟初始化”。请参阅CppCoreGuidelines C.49:在构造函数中优先进行初始化而不是赋值