【问题标题】:c++ some stack and heap understandingc++一些栈和堆的理解
【发布时间】:2014-11-12 12:27:34
【问题描述】:

请回答一些问题和声明以确认或修改以防万一。 我想确保我做对了,我很感谢任何提示。此外,我可以想象这些示例作为一个整体对 C++ 初学者有一定的价值。

  1. 堆栈启动对象

MyClass c(10);
MyClass c = MyClass(10);

据我了解,这两个对象初始化可以互换使用,对吗? 此外,当它们超出范围时会自动清理它们,例如从函数中返回。

  1. 堆启动对象

MyClass* c = new MyClass(10);

这个对象需要手动清理,比如“delete c”。

  1. 对象错误功能

MyClass* getObj() {
        MyClass c(10); // stack initiated object
        return &c;
}

这将返回一个指向我的堆栈范围的 MyClass 对象的指针(因为我没有使用 new 关键字)。 事实上,我不应该使用返回给它的指针,因为在使用时该对象可能已经被清理或稍后失败。对吗?

  1. 有效的对象复制功能

MyClass getObj() {
        MyClass c(10); // stack initiated object
        return c;
}

在这种情况下,堆栈启动对象的副本将返回对调用者的范围有效,对吗?

提前谢谢你。

亲切的问候, 赫尔曼

【问题讨论】:

标签: c++ object heap-memory stack-memory


【解决方案1】:

1°) 是的,但是如果您想安全起见,则不应使用语法MyClass a(10);,因为您可能会遇到most vexing parse 问题。理想情况下,您可以使用以下语法(假设为 c++11)来表达初始化而没有任何歧义:

MyClass a{10};

2°) 是的。但是你应该依赖RAII,并尽可能使用智能指针来分配资源。

3°) 这很糟糕,因为您返回的指针指向离开函数时已自动释放的内存(当本地对象c 已被销毁时)。

4°) 是的,但更好的是,使用named value return optimization,你甚至不应该得到一个副本,因为编译器通常足够聪明,可以看出销毁本地对象并返回一个副本是没有意义的。

【讨论】:

  • 请注意,在 1) T t = T(args); 要求类型是可复制的或移动可复制的。
  • @juanchopanza 哦?我想我在某处看到编译器通常能够将此表达式简化为一个简单的 ctor 调用当类型完全相同时,只要没有隐含的转换。
  • 编译器可以省略复制,否则只要遵循“as-if”规则就可以为所欲为,但代码仍然需要有效,并且复制或移动-副本是必需的,即使实际上没有复制。见ideone.com/KFxbaA
猜你喜欢
  • 1970-01-01
  • 2014-08-06
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2021-04-28
  • 2021-12-04
相关资源
最近更新 更多