如果这个copy constructor类没有这个对象可以移动吗?换句话说,一个类有move constructor而它的copy constructor被标记为删除是否合法。如果可以,它是否违反了三规则,五规则?
我知道五法则,它指出如果你实现一个析构函数,你很可能还应该实现一个复制构造函数、复制赋值运算符、一个移动构造函数和一个移动赋值运算符。
但是,如果我实现了一个移动运算符,我是否绝对必须实现一个副本副本,还是只是最佳实践?
我一整天都在这工作,所以我希望我不会忘记任何重要的细节,但是这里有.我最初的目标是拥有一个封装了如何创建播放器的逻辑的播放器工厂.
这是看起来像:
Player PlayerFactory::CreatePlayer() {
Player constructee(id_generator++);
// c++1x move semantics says this isn't a copy!
return constructee;
}
Run Code Online (Sandbox Code Playgroud)
在播放器中,有一个复合的PlayerInputComponent成员变量.这个PlayerInputComponent对象封装了处理玩家输入的逻辑,为此,它需要一个指向实际玩家本身的引用/指针.很容易,它引用了播放器,因为它是它的构造函数的唯一参数.
构造播放器对象时,它的初始化列表将对自身的引用传递给PlayerInputComponent对象.以下是它的外观:
Player::Player(const unsigned int id)
: id(id),
input_component(*this)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我知道在初始化列表中取消引用它通常是一个坏主意,但我只是用它在PlayerInputComponent对象中设置引用.这是构造函数:
PlayerInputComponent::PlayerInputComponent(Player &player)
: player_entity(player) { // set the reference, it is never used within the constructor body
}
Run Code Online (Sandbox Code Playgroud)
无论出于何种原因,当玩家工厂返回其创建的玩家的本地副本时,引用会出现乱码.我的意图是,在堆栈上创建的玩家的实例被移动并分配给被调用者.这看起来如下:
auto player = player_factory.CreatePlayer();
Run Code Online (Sandbox Code Playgroud)
代码执行后,播放器的复合PlayerInputComponent对象对它的引用被破坏了.我知道当工厂将本地播放器对象返回给被调用者时,会调用播放器的移动构造函数,但是PlayerInputComponent中播放器的引用会发生什么?有没有更好的方法来解决这个问题?我喜欢在这种情况下使用引用vs指针的语义,虽然我确实用指针尝试它并得到相同的东西.
任何人都可以向我解释当玩家对象移出CreatePlayer()成员函数并分配给"自动播放器"时,PlayerInputComponent对玩家的引用会发生什么?
为了完整性,这里是对象的声明:
class PlayerInputComponent {
private:
Player &player_entity;
void HandleKeyboardInput();
public:
//PlayerInputComponent(PlayerInputComponent &&other);
//PlayerInputComponent(const PlayerInputComponent &other);
PlayerInputComponent(Player &player);
void Update();
};
Run Code Online (Sandbox Code Playgroud)
这是玩家:
class Player …Run Code Online (Sandbox Code Playgroud) 我经常遇到这个问题,我相信移动构造函数是有序的,但我认为复制构造函数是问题,隐藏它似乎不起作用.
代码:
template <class T>
class LinkedList{
public:
//
LinkedList() {}
LinkedList(const T &data);
LinkedList(const T &data, const LinkedList &node);
LinkedList(const LinkedList &object);
LinkedList &operator=(const LinkedList &object);
~LinkedList() {}
std::shared_ptr<LinkedList> push_back(const T& data);
private:
T data;
std::unique_ptr<LinkedList> link;
std::unique_ptr<LinkedList> LinkFactory(const LinkedList &node);
std::shared_ptr<LinkedList> CreateStartNode(const T &data);
std::shared_ptr<LinkedList> CreateNode(const T &data, const LinkedList &node);
};
Run Code Online (Sandbox Code Playgroud)
发生错误的特定行是:
LinkedList<T>::LinkedList(const LinkedList<T> &object) : data(object.data),
link(std::move(object.link)) {}
Run Code Online (Sandbox Code Playgroud)
我试图移动而不是复制复制构造函数中的链接无济于事.如果设计移动构造函数而不是合成,那会更好吗?
最近我一直在研究C++ 11中的移动语义.我印象非常深刻,以至于我迫不及待地试着把它弄脏了.以下是我的代码:
#include <iostream>
using namespace std;
class ArrayWrapper
{
public:
// default constructor produces a moderately sized array
ArrayWrapper ()
: _p_vals( new int[ 64 ] )
, _size( 64 )
{
cout << "Default constructor: " << this << endl;
}
explicit ArrayWrapper (int n)
: _p_vals( new int[ n ] )
, _size( n )
{
cout << "Constructor: " << this << endl;
}
// move constructor
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals )
, _size( …Run Code Online (Sandbox Code Playgroud) 我有一个CustomException实现的类,std::exception其中我明确地删除了副本并移动构造函数.当我抛出该类的异常时,编译错误以调用已删除的构造函数.
是否在某处创建了CustomException实例?抛出异常时会创建哪些对象?
我有以下代码:
#include <iostream>
class foo_class {
std::string value;
public:
foo_class(const foo_class& v) : value{v.value} {
std::cout << "copy constructor" << std::endl;
}
foo_class(foo_class&& v) : value{std::move(v.value)} {
std::cout << "move constructor" << std::endl;
}
~foo_class() {
std::cout << "destructor" << std::endl;
}
foo_class(std::string v) : value{std::move(v)} {
std::cout << "type constructor" << std::endl;
}
};
struct Data {
foo_class a;
foo_class b;
};
int main() {
std::string c = "3";
Data x{c,c+"3"};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
重要的是,我使用GCC和Clang(分别为4.8.2和3.4)和标志-fno-elide-constructors进行编译,因此我们不会忽略复制/移动构造函数.
执行结果如下: …
我正在查看以下有关移动构造函数/赋值的示例:https: //msdn.microsoft.com/en-us/library/dd293665.aspx
我通过添加交换函数来修改它,以简化移动构造函数/赋值和复制赋值:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class MemoryBlock
{
public:
// Simple constructor that initializes the resource.
explicit MemoryBlock(size_t length)
: _length(length)
, _data(new int[length])
{
std::cout << "In MemoryBlock(size_t). length = "
<< _length << "." << std::endl;
}
// Destructor.
~MemoryBlock()
{
std::cout << "In ~MemoryBlock(). length = "
<< _length << ".";
if (_data != nullptr)
{
std::cout << " Deleting resource.";
// Delete the resource.
delete[] _data;
} …Run Code Online (Sandbox Code Playgroud) 我正在执行一些关于移动语义的测试,我的类行为对我来说似乎很奇怪。
鉴于模拟类VecOfInt:
class VecOfInt {
public:
VecOfInt(size_t num) : m_size(num), m_data(new int[m_size]) {}
~VecOfInt() { delete[] m_data; }
VecOfInt(VecOfInt const& other) : m_size(other.m_size), m_data(new int[m_size]) {
std::cout << "copy..." <<std::endl;
std::copy(other.m_data, other.m_data + m_size, m_data);
}
VecOfInt(VecOfInt&& other) : m_size(other.m_size) {
std::cout << "move..." << std::endl;
m_data = other.m_data;
other.m_data = nullptr;
}
VecOfInt& operator=(VecOfInt const& other) {
std::cout << "copy assignment..." << std::endl;
m_size = other.m_size;
delete m_data;
m_data = nullptr;
m_data = new int[m_size];
m_data …Run Code Online (Sandbox Code Playgroud) 我正在使用嵌入式模板化库 etl::queue
https://www.etlcpp.com/queue.html
在etl::queueIS quitvalent到std::queue
为了避免复制,我想将元素实际移动到队列中。
现在我的设置看起来像这样
bool CETLConcurrentQueue<ElementType_T, u32QueueSize>::Add(ElementType_T &&element, const uint32_t u32Timeout)
{
//lock mutex...
queue.push(element);
//do further stuff
}
Run Code Online (Sandbox Code Playgroud)
现在我不使用了,queue.push(std::move(element));因为 element 已经是一个右值引用了
但是,queue.push(element);调用元素复制构造函数(已删除)如何改为调用元素移动构造函数?
c++ ×10
move-constructor ×10
c++11 ×8
constructor ×2
exception ×1
reference ×1
stdvector ×1
unique-ptr ×1