2017-11-25 118 views
2

目前,我正在学习C++,并琢磨一下其中之一就是使用std ::移动哪个构造函数会触发移动语义?

//Code might be incorrect since I havent tested it out 
Xyt::ByteArray* Xyt::ResourceManager::LoadFileToByteArray(std::string Path) 
{ 
try { 
    std::ifstream FileStream(Path, std::ios::in); 
    std::ifstream::pos_type Pos = FileStream.tellg(); 

    FileStream.seekg(0, std::ios::beg); 

    std::vector<char> Buff(Pos); 
    FileStream.read(Buff.data(), Pos); 

    FileStream.close(); 

    //I want to trigger the move constructor here 
    return new Xyt::ByteArray(std::move(Buff)); 
} 
catch (std::exception e) { 
    std::cout << "ERROR::FILE::FILE_NOT_SUCCESFULLY_READ" << Path << std::endl; 
    return nullptr; 
    } 
} 

我感到困惑的是哪一个会引发性病,此举构造正确的方式::矢量?

它是这一个(编译错误时,主叫方犯规使用std ::移动)

Xyt::ByteArray::ByteArray(std::vector<char>&& Buffer) 
{ 
    this->Buffer = Buffer; 
} 

这一个(同时接受的std ::移动(浅黄色)和浅黄色)?

Xyt::ByteArray::ByteArray(std::vector<char> Buffer) 
{ 
    this->Buffer = Buffer; 
} 

or this one?

Xyt::ByteArray::ByteArray(std::vector<char> Buffer) 
{ 
    this->Buffer = std::move(Buffer); 
} 

我从阅读在互联网,即第一构造是利用移动语义的正确方法的理解。但是,如果我使用第一个构造函数,这是否意味着我需要做另一个构造函数,如果我想实际上在std :: vector Buff上进行复制?

任何帮助,将不胜感激!

回答

2

唯一有效的是第三个。但那是因为你在里面使用了std::move这个构造函数。它会引发两种动作:一种是填充参数,另一种是将参数填入数值中。

正确的方式做,这就是:

Xyt::ByteArray::ByteArray(std::vector<char>&& Buf) 
    : Buffer(std::move(Buf)) 
{} 

这只能调用移动操作一次。

如果要调用移动操作,则必须从指定的右值引用显式移出。


但是,如果使用1号构造是否意味着我需要另一个构造函数,如果我想实际的性病::向量的Buff做一个副本?

你并不严格要。你可以要求用户做复制自己,当他们打电话的功能:

Xyt::ByteArray(std::vector<char>(Buff)) 

但是,是的,如果你希望用户直接提供一个左值,并且希望从左值复制,那么你就需要提供一个构造函数需要(const)左值引用并执行副本。

+0

我想我明白了。还有一件事, Xyt :: ByteArray :: ByteArray(std :: vector && Buffer) this-> Buffer = std :: move(Buffer); },如果做这样一个std ::移动,这会调用移动构造函数两次类似于第三个构造函数吗? – Xyten

+1

@ Xyten:不会。它根本不会调用move *构造函数*。它会调用move * assignment *,因为'ByteArray :: Buffer'是一个*活动对象*。这就是为什么我使用成员初始化器;这就是你对成员进行初始化的地方。 –

相关问题