Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 移动共享向量的构造函数\u ptr<;MyClass>;_C++_Boost_C++11_Move_Shared Ptr - Fatal编程技术网

C++ 移动共享向量的构造函数\u ptr<;MyClass>;

C++ 移动共享向量的构造函数\u ptr<;MyClass>;,c++,boost,c++11,move,shared-ptr,C++,Boost,C++11,Move,Shared Ptr,我理解如果您希望传递MyClass对象的向量,并且它是一个临时变量,如果有为MyClass定义的移动构造函数,那么将调用它,但是如果您传递boost::shared_ptr或std::shared_ptr的向量,会发生什么?共享\u ptr是否有一个移动构造函数,然后调用MyClass的移动构造函数?是的,std::shared\u ptr有一个移动构造函数,以及一个可以从相关共享指针移动的模板化构造函数,但它根本不接触托管对象。新构造的共享指针共享托管对象(如果有)的所有权,而“从中移出”指针

我理解如果您希望传递MyClass对象的向量,并且它是一个临时变量,如果有为MyClass定义的移动构造函数,那么将调用它,但是如果您传递
boost::shared_ptr
std::shared_ptr
的向量,会发生什么?共享\u ptr是否有一个移动构造函数,然后调用MyClass的移动构造函数?

是的,
std::shared\u ptr
有一个移动构造函数,以及一个可以从相关共享指针移动的模板化构造函数,但它根本不接触托管对象。新构造的共享指针共享托管对象(如果有)的所有权,而“从中移出”指针是分离的(“null”)

例如:

struct Base {};                // N.B.: No need for a virtual destructor
struct Derived : Base {};

auto p = std::make_shared<Derived>();
std::shared_ptr<Base> q = std::move(p);

assert(!p);
struct Base{};//注意:不需要虚拟析构函数
派生结构:基{};
自动p=std::使_共享();
std::shared_ptr q=std::move(p);
断言(!p);

是,
std::shared\u ptr
有一个移动构造函数,以及一个可以从相关共享指针移动的模板化构造函数,但它根本不涉及托管对象。新构造的共享指针共享托管对象(如果有)的所有权,而“从中移出”指针是分离的(“null”)

例如:

struct Base {};                // N.B.: No need for a virtual destructor
struct Derived : Base {};

auto p = std::make_shared<Derived>();
std::shared_ptr<Base> q = std::move(p);

assert(!p);
struct Base{};//注意:不需要虚拟析构函数
派生结构:基{};
自动p=std::使_共享();
std::shared_ptr q=std::move(p);
断言(!p);
如果有为MyClass定义的移动构造函数,则将调用该构造函数

通常不会。移动向量通常是在转移托管阵列的所有权时完成的,将“从向量移动”保留为空。物体本身不会被触碰。(我认为如果这两个向量有不兼容的分配器,可能会有一个例外,但这超出了我需要处理的范围,因此我不确定其中的细节)

共享的ptr是否有一个移动构造函数,然后调用MyClass的移动构造函数

否。同样,它有一个move构造函数,它将
MyClass
对象的所有权转移到新指针,使旧指针为空。对象本身未被触及

如果有为MyClass定义的移动构造函数,则将调用该构造函数

通常不会。移动向量通常是在转移托管阵列的所有权时完成的,将“从向量移动”保留为空。物体本身不会被触碰。(我认为如果这两个向量有不兼容的分配器,可能会有一个例外,但这超出了我需要处理的范围,因此我不确定其中的细节)

共享的ptr是否有一个移动构造函数,然后调用MyClass的移动构造函数


否。同样,它有一个move构造函数,它将
MyClass
对象的所有权转移到新指针,使旧指针为空。对象本身未被触碰。

如果您的意思是移动
std::vector
。那么即使是
std::shared_ptr
的move构造函数也不会被调用。因为移动操作直接在
std::vector
级别上完成

例如,
std::vector
可以实现为指向
T
数组的指针和
size
成员。此项的移动构造函数可以实现为:

template <typename T>
class vector {
public:
    /* ... other members */
    vector(vector &&another): _p(another._p), _size(another._size) {
        /* Transfer data ownership */
        another._p = nullptr;
        another._size = 0;
    }

private:
    T *_p;
    size_t _size;
}
C++标准:这两个(移动构造函数)对于除
std::array
之外的所有标准容器都应该具有恒定的时间复杂度

因此很容易得出结论,实现必须使用我在上文中为
std::vector
的move构造函数指出的方法,因为它不能调用单个元素的move构造函数,否则时间复杂性将变成线性时间

a = rv
C++标准:
a
的所有现有元素要么被移动分配给a,要么被销毁a应等于
rv
在此分配之前的值

这是用于移动分配运算符的。这句话只说明
a
中的原始元素应“正确处理”(移动分配或销毁)。但这并不是一个严格的要求。IMHO实施可以选择最适合的方式

我还查看了VisualC++ 2013中的代码,这是我发现的代码段(<代码> vector <代码>标题,从第836行开始):

/*直接移动,就像上面的代码一样*/
void\u Assign\u rv(\u Myt&&u Right,true\u type)
{//从_向右移动,窃取其内容
这个->交换所有的(((Myt&)对);
这个->\u Myfirst=\u Right.\u Myfirst;
这个->\u Mylast=\u Right.\u Mylast;
这个->\u Myend=\u Right.\u Myend;
_右。_Myfirst=指针();
_右。_Mylast=pointer();
_右。_Myend=pointer();
}
/*移动赋值运算符和移动构造函数都将调用此函数*/
无效分配rv(_Myt&&&u Right,假类型)
{//从_向右移动,可能移动其内容
if(get_allocator()==\u Right.get_allocator())
_分配_rv(_stdforward(_Right),true_type());
其他的
_构造(_stdmake_move_迭代器(_Right.begin()),
_STD make_move_迭代器(_Right.end());
}

在这段代码中,操作是明确的:如果
this
right
操作数具有相同的分配器,它将直接窃取内容,而不对单个元素执行任何操作。但如果没有,则将调用单个元素的移动操作。此时,其他答案也适用(适用于
std::shared_ptr
东西)。

如果您的意思是移动
std::vector
。那么即使是
std::shared_ptr
的move构造函数也不会被调用。因为移动操作直接在
std::vector
级别上完成

例如,
std::vector
可以实现为指向
T
数组的指针和
size
成员。此项的移动构造函数可以实现为:

template <typename T>
class vector {
public:
    /* ... other members */
    vector(vector &&another): _p(another._p), _size(another._size) {
        /* Transfer data ownership */
        another._p = nullptr;
        another._size = 0;
    }

private:
    T *_p;
    size_t _size;
}
C++标准:这两个(移动构造函数)对于所有标准都应该具有恒定的时间复杂度