std::vector 和构造函数

发布于 2024-11-14 03:35:49 字数 460 浏览 1 评论 0原文

当 std::vector 创建它所包含的对象的新实例时,它会调用哪个构造函数?我的印象是它调用了默认构造函数,但如果未定义默认构造函数或者编译器正在为我执行此操作怎么办?

特别是在这样的情况下:

class Foo
{
    public:
        Foo(int size)
        {
            data = new double[size];
        }


        ~Foo()
        {
            delete[] data;
        }

    private:
        double* data;
};

std::vector<Foo> myVector;
Foo bar(5);
myVector.push_back(bar);
//stuff

当对象在构造之后大小未知时,它如何知道要分配多少内存?

Which constructor does std::vector call when it is making a new instance of the object it's containing? I am under the impression it calls a default constructor but what if one is not defined or is the compiler doing that for me?

Particularly in a case as such:

class Foo
{
    public:
        Foo(int size)
        {
            data = new double[size];
        }


        ~Foo()
        {
            delete[] data;
        }

    private:
        double* data;
};

std::vector<Foo> myVector;
Foo bar(5);
myVector.push_back(bar);
//stuff

How does it know how much memory to allocate when the object has an unknown size until after construction?

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

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

发布评论

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

评论(2

枯叶蝶 2024-11-21 03:35:49

至少,要编译 std::vectorT 必须是可复制构造和可复制分配的。如果您想使用 std::vector::vector(int) (或 std::vector::resize()),则 < code>T 必须是默认可构造的。如果不满足其中任何一个要求,代码将无法编译。

...

C++03 标准,第 23.1 节(一般讨论容器):

存储在这些组件中的对象类型必须满足 CopyConstructible 类型 (20.1.3) 的要求,以及 Assignable 类型的附加要求。

第 20.1.4 节:

20.1.4 默认构造

不需要默认构造函数。某些容器类成员函数签名将默认构造函数指定为默认参数。如果使用默认参数 (8.3.6) 调用这些签名之一,则 T() 应是一个明确定义的表达式 (8.5)。

At a minimum, for std::vector<T> to compile, T must be copy-constructible, and copy-assignable. If you want to use std::vector<T>::vector(int) (or std::vector<T>::resize()), then T must have be default-constructible. If any of these requirements are not fulfilled, the code will not compile.

...

C++03 standard, section 23.1 (discussing containers in general):

The type of objects stored in these components must meet the requirements of CopyConstructible types (20.1.3), and the additional requirements of Assignable types.

Section 20.1.4:

20.1.4 Default construction

The default constructor is not required. Certain container class member function signatures specify the default constructor as a default argument. T() shall be a well-defined expression (8.5) if one of those signatures is called using the default argument (8.3.6).

吖咩 2024-11-21 03:35:49

修复错误后会发生什么:

std::vector<Foo> myVector;
myVector.reserve(10);
myVector.push_back(bar);

有两个 Foo 实例指向同一个 data 缓冲区。它可能会工作一段时间,但最终两个对象都会被销毁,析构函数被调用两次(或更多,取决于 vector 是否需要移动其内容)并且缓冲区是双倍的-freed,导致未定义的行为(通常意味着崩溃)。


为了解决向量的初始内容,它复制构造您作为参数传入的模式(此参数默认为默认构造的对象,但并非必须如此):

std::vector<Foo> myVector(10, bar); // 10 copies of bar

What happens, after you fix the error:

std::vector<Foo> myVector;
myVector.reserve(10);
myVector.push_back(bar);

is that you have two Foo instances pointing to the same data buffer. It will probably appear to work for a while, but eventually both objects get destroyed, the destructor is called twice (or more, depending on whether the vector needs to move its content around) and the buffer is double-freed, resulting in undefined behavior (which usually means crash).


To address the initial content of the vector, it copy-constructs the pattern you pass in as a parameter (this parameter defaults to a default-constructed object, but doesn't have to be):

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