C++初始化列表和内存分配

发布于 2024-08-06 14:11:42 字数 345 浏览 7 评论 0原文

以下内容有效吗?

class myClass
{
   private:
     ...
     int m_nDataLength;
     boost::shared_array<int> m_pData;
     ...

   public:
     myClass(): ..., m_nDataLength(10), m_pData(new int[m_nDataLength]), ...
     {
     }
}

我是否正确地假设初始化将完全按照我在构造函数中给出的顺序进行?如果不是,如果 m_nDataLength 的初始化发生在 m_pData 之后怎么办?

Is the following valid?

class myClass
{
   private:
     ...
     int m_nDataLength;
     boost::shared_array<int> m_pData;
     ...

   public:
     myClass(): ..., m_nDataLength(10), m_pData(new int[m_nDataLength]), ...
     {
     }
}

Am I right in assuming that the initialization will happen exactly in the order I've given in the ctor? If not, what if m_nDataLength's initialization happens after m_pData's?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浴红衣 2024-08-13 14:11:42

虽然示例中的初始化确实按照您想要的顺序进行,但这并不是您假设的原因:初始化按照类定义中数据成员声明的顺序进行。 这样做的原因是,无论使用哪个构造函数来创建对象,析构函数都必须按向后顺序销毁成员。为此,必须使用独立于构造函数的方式来定义构造顺序。

这意味着,如果不是

class myClass
{
   private:
     ...
     int m_nDataLength;
     boost::shared_array<int> m_pData;

有人更改您的代码,

class myClass
{
   private:
     ...
     boost::shared_array<int> m_pData;
     int m_nDataLength;

那么该代码就会出现错误。

我的建议是:

  • 编写构造函数,以便初始化顺序无关紧要。
  • 如果你做不到这一点(注意:对我来说,这种情况在过去十年中发生了不到 5 次),请在声明数据成员时完全清楚地说明这一点。

像这样的事情应该做:

class myClass
{
   private:
     ...
     int m_nDataLength;                 // Note: Declaration order
     boost::shared_array<int> m_pData;  //       matters here!

While the initialization in your example does happen in the order you want, it's not for the reason you assume: Initialization happens in the order of the data members declaration in the class definition. The reason for this is that the destructor must destroy the members in backward order not matter which constructor was used to create the object. For that, a constructor-independent way of defining the construction order must be used.

That means that, if instead of

class myClass
{
   private:
     ...
     int m_nDataLength;
     boost::shared_array<int> m_pData;

someone would change your code to

class myClass
{
   private:
     ...
     boost::shared_array<int> m_pData;
     int m_nDataLength;

then the code would have a bug.

My advice is:

  • Write your constructors so that the initialiszation order doesn't matter.
  • If you cannot do this (note: to me this happened less than 5 times in the last decade), make it completely clear at the point the data members are declared.

Something like this should do:

class myClass
{
   private:
     ...
     int m_nDataLength;                 // Note: Declaration order
     boost::shared_array<int> m_pData;  //       matters here!
半世晨晓 2024-08-13 14:11:42

初始化将按类中的顺序初始化字段,因此:如果您进行更改

private:
  ...
  int m_nDataLength;
  boost::shared_array<int> m_pData;

private:
  ...
  boost::shared_array<int> m_pData;
  int m_nDataLength;

它将不起作用。在构造函数中,该顺序不适用。

the initialization will initialize fields by order in class, so: if you change

private:
  ...
  int m_nDataLength;
  boost::shared_array<int> m_pData;

as

private:
  ...
  boost::shared_array<int> m_pData;
  int m_nDataLength;

it wont work. In constructor, the order doesn't apply.

小梨窩很甜 2024-08-13 14:11:42

不,类成员的初始化按照成员在类定义中出现的顺序进行。如果成员出现在初始值设定项列表中,则控制用于初始化该成员的表达式(即使它使用尚未初始化的成员),但它在初始值设定项列表中出现的位置不会影响其初始化时间。

No, initialization for class members happens in the order that the members appear in the class definition. If a member appears in the initializer list, then that controls the expression used to initialize that member (even if it uses a member that has not yet been initialized) but where it appears in the initializer list does not affect when it is initialized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文