首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >移动构造器&移动分配

移动构造器&移动分配
EN

Stack Overflow用户
提问于 2017-09-23 13:18:40
回答 1查看 2.2K关注 0票数 3

我一直在阅读Bjarne ( C++的创建者)的“C++编程语言第4版”一书,并且一直在学习移动构造函数和移动任务。

在关于类向量的书中(见下面的头1),他展示了如何实现移动构造函数(参见下面的2),并说移动分配是以类似的方式实现的,但没有说明如何实现。我自己实现了移动任务(见下面3),一切看起来都很好,但是,我不确定我是否正确地实现了它。

我没有收到任何错误,并看了许多例子,但我不能确定它的正确,我的具体课程。是否有人对c++有经验,请看我的代码和评论,如果它是正确的?

编辑:也请参见4用于构造函数和析构函数.

谢谢您抽时间见我。

P.S:欢迎任何有用的提示或修改

1)类头文件:

代码语言:javascript
复制
#ifndef VECTOR_H
#define VECTOR_H

#include <cstdlib>
#include <iostream>
#include <stdexcept>

using namespace std;

template<typename T>
class Vector {

public:
    // constructors
    Vector(int s);
    Vector(std::initializer_list<T>);

    // destructor
    ~Vector();

    // copy constructor and copy assignment
    Vector(Vector&);
    Vector<T>& operator=(Vector&);

    // move constructor and move assignment
    Vector(Vector&&);
    Vector<T>& operator=(Vector&&);

    // operators
    T& operator[](int);
    const T& operator[](int) const; // the second const means that this function cannot change the state of the class
                                    // we define operator[] the second time for vectors containing constant members;
    // accessors
    int getSize();


private:
    int size;
    T* elements;

};

#endif /* VECTOR_H */

2)移动构造函数(以与book相同的方式实现):

代码语言:javascript
复制
// move constructor 
template<typename T>
Vector<T>::Vector(Vector&& moveme) : size{moveme.size}, elements{moveme.elements}
{
    moveme.elements = nullptr;
    moveme.size = 0;
}

3)移动任务(不确定是否正确):

代码语言:javascript
复制
// move assignment
template<typename T>
Vector<T>& Vector<T>::operator=(Vector&& moveme) 
{
    delete[] elements; // delete old values
    elements = moveme.elements;
    size = moveme.size;
    moveme.elements = nullptr;
    moveme.size = 0;
    return *this;
}

4)建设者和破坏者:

代码语言:javascript
复制
#include <array>

#include "Vector.h"

// constructors
template<typename T>
Vector<T>::Vector(int s) {    
    if(s<0) throw length_error{"Vector::Vector(int s)"};
    // TODO: use Negative_size{} after learning how to write custom exceptions
    this->size = s;
    this->elements = new T[s];
}

template<typename T>
Vector<T>::Vector(std::initializer_list<T> list) : size(list.size()), 
        elements(new T[list.size()]) 
{
    copy(list.begin(), list.end(), elements);
}

// destructor
template<typename T>
Vector<T>::~Vector()
{
    delete[] this->elements;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-01 09:08:03

由于这个问题在评论中得到了回答,我想我应该遵循meta的建议:Question with no answers, but issue solved in the comments (or extended in chat),并编写一个简短的Community来结束并回答这个问题。

我也将添加有用的额外信息和提示,从其他用户谁参加了讨论在评论。

Bo Presson回答并提供关于模板放置的其他信息:

移动分配似乎是合理的,除了将模板放在cpp文件中使它们只在cpp文件中可用。请参阅Why can templates only be implemented in the header file?

Rakete1111澄清了我对移动语义的误解:

移动!=移动语义。您有移动语义,其中rvalue可以被移动(使用move构造函数),而不是复制。std::move只是一种工具,用于对非rvalue的类型启用移动语义(比如使用move构造函数)。

kim366提出了返回优化问题,Jive Dadson和我回答:

..。另外,如果没有重载的移动ctors/赋值,是否真的没有返回值优化?-kim366 似乎是这样的,在这个例子中(参见下面的函数),他说z = x + y + z将复制两次返回结果,“如果向量很大,比如10,000倍,这可能会令人尴尬。”但是“给定该定义,编译器将选择move构造函数来实现返回值的传输.”他发明了病得很重的c++ --相信他的话吧:)Vector operator+(const Vector& a, const Vector& b) { if (a.size()!=b.size()) throw Vector_size_mismatch{}; Vector res(a.size()); for (int i=0; i!=a.size(); ++i) res[i]=a[i]+b[i]; return res; } -锤击 (例子来自的“C++编程语言第4版”一书) 另见What is the copy-and-swap idiom? -Jive Dadson

希望人们发现这是有用的,感谢那些参与的人。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46380008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档