gpt4 book ai didi

c++ - 通过例程初始化聚合

转载 作者:行者123 更新时间:2023-11-28 07:23:23 25 4
gpt4 key购买 nike

我正在使用例程来初始化类的聚合成员。

class MyClass
{
public:
void Init()
{
double array2D[10][10] = {0.0};
bool logicalarray[2] = {false};
}

private:
double array2D[10][10];
bool logicalarray[2];
};

int main()
{
MyClass* myClassObject = new MyClass();
myClassObject->Init();

delete myClassObject;
return 0;
}

这有什么问题吗?它编译、构建和运行良好。在调试时,我确实看到每个数组元素都按照我在 Init() 中定义的方式进行了初始化。但是,代码清理工具报告在 Init() 中声明了命名变量但未引用。

附言:没有 C++11

最佳答案

代码清理工具是对的。这段代码并不像您想象的那样:

void Init()
{
double array2D[10][10] = {0.0};
bool logicalarray[2] = {false};
}

认为这段代码初始化了MyClass 的成员变量。它实际上做的是声明两个局部(自动)变量,初始化它们,然后返回。成员变量没有被触及,并且是 hiddenInit() 的主体内。

您可以通过以下方式解决此问题:

void Init()
{
array2D[10][10] = {0.0};
logicalarray[2] = {false};
}

但我认为这在技术上是正确的,但仍然是错误的。您正在使用所谓的两阶段 build 。这两个阶段是:1) 构造一个MyObject。 2) 通过调用 Init() 函数初始化 MyObject

丑陋的。可恶的。容易出错和健忘。语义上不正确,因为构造函数不会使对象处于完全初始化状态。作为一般规则,您应该不惜一切代价避免两阶段施工。更好的方法是在对象的构造函数中执行所有初始化——最好是在成员初始化列表中,但这对于聚合成员来说很难/不可能。在这些情况下,在构造函数的主体中进行初始化:

class MyClass
{
public:
MyClass ()
{
array2D[10][10] = {0.0};
logicalarray[2] = {false};
}
// ...
};

现在,MyObject 的构造也意味着MyObject初始化。毕竟,这就是构造函数的用途。改为这样做。

这里的问题是我们不能像这样初始化聚合。我们只能在构造时使用此语法初始化聚合,但这发生在(不存在的)初始化列表中。我们不能使用 C++03 中的初始化列表来初始化聚合。所以你留下了一个丑陋的情况:

MyClass ()
{
memset (logicalarray, logicalarray+2, 0);
memset (array2D, array2D+sizeof (array2D), 0);
}

这让我想到了一个论点,即您首先不应该使用原始数组,而应该使用 vector(或其他东西)并通过类似的方式对其进行初始化:

   class MyClass
{
public:
std::vector <bool> mBools;
std::vector <std::vector <double> > mDoubles;
MyClass ()
{
std::fill_n (std::back_inserter (mBools), 2, false);
}
};

我将把 mDoubles 的初始化留作练习。

关于c++ - 通过例程初始化聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19096137/

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