什么是C ++对象的生命周期?

什么是C ++对象的生命周期?

问题描述:

我是一位经验丰富的C开发人员,刚刚进入C ++,我必须承认,我对创建,保留和销毁C ++对象有多少种方法感到非常困惑.在C语言中,生活很简单:在堆栈上使用=副本进行赋值,而在堆栈中使用malloc/free来管理数据. C ++远非如此,所以在我看来.

I'm a seasoned C developer who is just now getting into C++, and I must admit, I'm very confused about how many ways there are to create, retain, and destroy C++ objects. In C, life is simple: assignment with = copies on the stack, and malloc/free manage data on the heap. C++ is far from that, or so it seems to me.

鉴于此,这是我的问题:

In light of that, here are my questions:

  1. 所有所有创建C ++对象的方式是什么?直接/复制构造函数,赋值等.它们如何工作?
  2. 与所有这些类型的对象创建相关的所有不同初始化语法是什么? T f = xT f(x);T f{x};等之间有什么区别?
  3. 最重要的是,何时复制/分配/无论C ++中的=是否正确,以及何时要使用指针?在C语言中,我很习惯在 lot 周围抛出指针,因为指针分配很便宜,但结构复制却很少. C ++的复制语义如何影响这一点?
  4. 最后,所有这些东西是什么,例如shared_ptrweak_ptr等?
  1. What are all the ways to create a C++ object? Direct/copy constructor, assignment, etc. How do they work?
  2. What are all the different initialization syntaxes associated with all these types of object creation? What's the difference between T f = x, T f(x);, T f{x};, etc.?
  3. Most importantly, when is it correct to copy/assign/whatever = is in C++, and when do you want to use pointers? In C, I got very used to throwing pointers around a lot, because pointer assignment is cheap but struct copying is less so. How do C++'s copy semantics affect this?
  4. Finally, what are all these things like shared_ptr, weak_ptr, etc.?

很抱歉,如果这是一个比较广泛的问题,但是我对何时使用什么感到非常困惑(甚至没有提到我对集合和new运算符中的内存管理的困惑),我感到一切我知道C内存管理在C ++中会崩溃.是真的,还是我的思维模式是错误的?

I'm sorry if this is a somewhat broad question, but I'm very confused about when to use what (not even mentioning my confusion about memory management in collections and the new operator), and I feel like everything I knew about C memory management breaks down in C++. Is that true, or is my mental model just wrong?

总结一下:如何创建,初始化和销毁​​C ++对象,以及何时应使用每种方法?

To sum things up: how are C++ objects created, initialized, and destroyed, and when should I use each method?

首先,您的内存管理技能在C ++中很有用,只是它们低于C ++的处理方式,但是它们确实存在.

First of all, your memory management skills are useful in C++, just they are a level below the C++ way of doing things, but they are there...

关于您的问题,它们有点笼统,所以我将尽量简短:

About your questions, they are a bit broad, so I'll try to keep it short:

1)创建C ++对象的所有方式有哪些?

1) What are all the ways to create a C++ object?

与C相同:它们可以是全局变量,局部自动变量,局部静态变量或动态变量.您可能会对构造函数感到困惑,但是只是认为每次创建对象时都会调用一个构造函数.总是.哪个构造函数只是创建对象时使用什么参数的问题.

Same as C: they can be global variables, local automatic, local static or dynamic. You may be confused by the constructor, but simply think that every time you create an object, a constructor is called. Always. Which constructor is simply a matter of what parameters are used when creating the object.

赋值不会创建新对象,它只是从一个对象复制到另一个对象(以memcpy为例,但更聪明).

Assignment does not create a new object, it simply copies from one oject to another, (think of memcpy but smarter).

2)与所有这些类型的对象创建相关联的初始化语法分别是什么? T f = x,T f(x);、 T f {x};等之间有什么区别?

2) What are all the different initialization syntaxes associated with all these types of object creation? What's the difference between T f = x, T f(x);, T f{x};, etc.?

  • T f(x)是经典方法,它只是使用将x作为参数的构造函数来创建类型为T的对象.
  • T f{x}是新的C ++ 11统一语法,因为它可用于初始化聚合类型(数组等),但除此之外,它等效于前者.
  • T f = x取决于x是否为T类型.如果是,则等效于前者,但是如果类型不同,则等效于T f = T(x).并不是真的很重要,因为允许编译器优化多余的副本(复制省略).
  • T(x).你忘了这个.创建一个临时类型为T的临时对象(使用与上述相同的构造函数),该临时对象将在代码中发生的任何地方使用,并且在当前完整表达式的结尾处将其销毁.
  • T f.这将使用默认构造函数(如果可用)创建类型为T的值.那只是一个不带参数的构造函数.
  • T f{}.默认构造,但具有新的统一语法.请注意,T f()不是类型为T的对象,而是返回T!的函数.
  • T().使用默认构造函数的临时对象.
    • T f(x) is the classic way, it simply creates an object of type T using the constructor that takes x as argument.
    • T f{x} is the new C++11 unified syntax, as it can be used to initialize aggregate types (arrays and such), but other than that it is equivalent to the former.
    • T f = x it depends on whether x is of type T. If it is, then it equivalent to the former, but if it is of different type, then it is equivalent to T f = T(x). Not that it really matters, because the compiler is allowed to optimize away the extra copy (copy elision).
    • T(x). You forgot this one. A temporary object of type T is created (using the same constructor as above), it is used whereever it happens in the code, and at the end of the current full expression, it is destroyed.
    • T f. This creates a value of type T using the default constructor, if available. That is simply a constructor that takes no parameters.
    • T f{}. Default contructed, but with the new unified syntax. Note that T f() is not an object of type T, but instead a function returning T!.
    • T(). A temporary object using the default constructor.
    • 3)最重要的是,什么时候在C ++中复制/分配/无论=什么是正确的,以及何时要使用指针?

      3) Most importantly, when is it correct to copy/assign/whatever = is in C++, and when do you want to use pointers?

      您可以使用与C中相同的名称.将副本/赋值视为memcpy所在的位置.您还可以传递引用,但是也可以等待一段时间,直到对这些内容感到满意为止.您应该做的是:不要将指针用作辅助局部变量,而应使用引用.

      You can use the same as in C. Think of the copy/assignment as if it where a memcpy. You can also pass references around, but you also may wait a while until you feel comfortable with those. What you should do, is: do not use pointers as auxiliary local variables, use references instead.

      4)最后,这些东西是什么,例如shared_ptr,weak_ptr等?

      4) Finally, what are all these things like shared_ptr, weak_ptr, etc.?

      它们是C ++工具带中的工具.您将不得不通过经验和一些错误来学习...

      They are tools in your C++ tool belt. You will have to learn through experience and some mistakes...

      • shared_ptr在共享对象的所有权时使用.
      • unique_ptr在对象的所有权是唯一且明确的情况下使用.
      • weak_ptr用于中断shared_ptr树中的循环.它们是自动检测到的.
      • vector.不要忘记这个!用它来创建任何事物的动态数组.
      • shared_ptr use when the ownership of the object is shared.
      • unique_ptr use when the ownership of the object is unique and unambiguous.
      • weak_ptr used to break loops in trees of shared_ptr. They are not detected automatically.
      • vector. Don't forget this one! Use it to create dynamic arrays of anything.

      PS:您忘了问有关析构函数的问题. IMO,析构函数是赋予C ++个性的原因,因此请务必使用很多!

      PS: You forgot to ask about destructors. IMO, destructors are what gives C++ its personality, so be sure to use a lot of them!