【问题标题】:C++ Struct declared inside a class在类中声明的 C++ Struct
【发布时间】:2014-12-05 04:30:44
【问题描述】:

长期读者第一次海报。搜索这个非常晦涩,所以我找不到任何东西。

任何人,如果我在一个类中声明一个结构。然后我有一个类方法可以创建所述结构的实例,创建的结构实例的生命周期是多少?

例如在我的标题中:

class test_class
{
     Public:
          void test_function(int, string);

     private:
          struct test_struct
          {
               int foo;
               string bar;
          };

          test_struct * storage;
}

然后在test_class.cpp中

void test_function(int num, string name)
{
     test_struct t1;
     t1.foo = num;
     t1.bar = name;

     storage = new test_struct [<some_size>];
     storage[<some_element>] = t1;
}

所以,我创建了一个 test_class 实例并调用了 test_function。 t1 已创建并成功存储在假设数组中,但它是否仍保存在数组中?或者当函数退出时它会因为范围变化而被删除? t1 是否成为类的成员变量?我需要 t1 作为指向 test_struct 的指针并拥有一个 test_struct 指针数组吗?

提前感谢您的帮助。

【问题讨论】:

  • 不要使用指针,而是使用std::vector&lt;test_struct&gt; storage;。然后一切都会自行处理。
  • 不幸的是,我必须这样做。这不是任务本身,而是对想法的简化。我代表一个优先级队列,其堆由数组@.@ 表示
  • A vector 完全符合您的伪代码试图做的事情,只是正确。向量调用 newdelete,与您尝试执行的操作没有什么不同(但同样,只是更安全)。
  • 明白。不幸的是,我必须使用数组。
  • 您的代码使用的是指针,而不是数组。再次阅读我的评论——向量以一种受控、安全的方式完全完成你正在做的事情。数组就在那里,你只需要得到它。此时,您的代码存在内存泄漏,因为您没有调用delete

标签: c++ arrays class pointers struct


【解决方案1】:

生命周期与类定义的嵌套无关。

此声明

 test_struct t1;

声明一个局部变量,其生命周期在包含声明的块的右大括号处结束。它声明了一个局部变量,因为它位于函数定义的块中。

此声明

 storage = new test_struct [<some_size>];

动态创建&lt;some_size&gt;test_struct 实例。该数组的生命周期在您delete[] 时结束。如果你这样做了。

此声明

storage[<some_element>] = t1;

是一个拷贝赋值,拷贝t1的值。它不会创建新实例。


查看SO C++ booklist 以找到适合您的 C++ 教科书。如果可以的话,找一个声望更高的人来帮助你,这样you can read the deleted answers。遗憾的是,现有的社区工作曾一度被删除,取而代之的是一份摘要。

【讨论】:

  • 感谢您回复我。那么结构实例 t1 是否被复制到存储数组的指定元素中?那么当函数退出时,原来的t1的生命周期就结束了,但是会在storage中保存一份副本,直到storage为delete [] storage;?
  • 优秀。再次感谢您的所有帮助。
【解决方案2】:

查看您的问题,您似乎对类中的结构类型感到困惑。如果有帮助,这里有一些解释 与

      struct test_struct
      {
           int foo;
           string bar;
      };

在类中,您刚刚创建了一个封装在类中的新类型。 (像对待任何其他类型一样对待它)。 回答您的问题 1.t1 被创建并成功存储在假设数组中,但它是否仍然保存在数组中?还是在函数退出时因为范围发生变化而被删除?

答案:是的,它复制到数组中,如上一个答案中所述。它是一个复制分配(按位复制语义),因此,您的数组元素现在具有从 t1 复制到它的值

  1. t1 是否成为类的成员变量?我需要 t1 作为指向 test_struct 的指针并拥有一个 test_struct 指针数组吗?

Answer: t1 是一个局部变量(分配在栈上),它不是类的成员变量。在堆上分配存储(新)后,您有一个 test_struct 元素数组,然后您只需将本地 t1 的值复制到您的数组中。本质上,您是在 t1 超出范围时将其销毁之前将 t1 的值复制到数组中。你不需要创建一个指向 test_struct 的指针的数组,(当然如果有一些强迫性的原因,在这种情况下你也可以为 test_struct 分配内存)。

您的“存储”成员是在堆上分配的,因此,请确保调用 delete[] 来回收内存。

希望对你有帮助!

【讨论】:

  • -1 “它是一个复制赋值(按位复制语义)”,不,它不是按位复制。甚至不是这个特定示例的特例。此示例包含一个 string 成员,调用其复制构造函数进行复制。
  • 这是什么声明?存储[] = t1;不是赋值操作吗?当分配发生时,成员将按位方式复制。但是,std::string 有自己的赋值实现来进行深拷贝。在完整理解该声明之前,不确定您为什么投反对票。
  • 通过赋值或构造复制不是按位复制。如果它被复制,那么指针将指向完全错误的东西,依此类推。通过memcpy 复制是(例如)按位复制。重新“成员将按位复制时尚”,不,一点也不。
  • 仅供参考en.wikipedia.org/wiki/Copy_constructor#Bitwise_Copy_Constructor 这就是我所说的按位复制“语义”的意思。此外,您的响应“字符串成员,其复制构造函数被调用来进行复制”是错误的。不,当 storage[] = t1;调用时,将调用字符串类的赋值运算符,而不是其复制构造函数。
  • 是的,我写的“复制构造函数”应该是“复制赋值运算符”。抱歉错字。无论如何,按位复制并不意味着复制构造函数或复制赋值运算符。 C++ 中没有“按位复制构造函数”之类的东西;维基百科的文章质量相当低且具有误导性。感谢您让人们意识到这一点。
猜你喜欢
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 2019-12-26
  • 2014-10-29
相关资源
最近更新 更多