据称不应该有好处的C ++移动语义
c++ move semantics where allegedly there shouldn't be benefit
我今天需要使用一些遵循此基本设计的类:
class Task {
public:
Task() {
Handler::instance().add(this);
}
virtual void doSomething() = 0;
};
class Handler {
std::vector<Task*> vec;
//yea yea, we are locking the option to use default constructor etc
public:
static Handler& instance() {
static Handler handler;
return handler;
}
void add(Task* task) {
vec.push_back(task);
}
void handle() {
for (auto t : vec) {
t->doSomething();
}
}
};
template <class T, int SIZE>
class MyTask : public Task {
T data[SIZE];
public:
virtual void doSomething() {
// actually do something
}
};
//somewhere in the code:
Handler::instance().handle();
现在,我的班级像
class A {
MyTask<bool, 128> myTask;
public:
A(int i) {}
};
我想这样做的方式是拥有一个a的示例为a是值的地图
static std::map<int, A> map = {
{42, A(1948)},
{88, A(-17)}
};
首先要澄清某些内容 - 此代码需要在实时嵌入式系统上运行,因此由于多种遗产原因,我不允许使用新的内存分配内存。
我的问题是,地图中的实际对象不是我明确创建的对象,因此它们没有在处理程序类中注册(因此我没有从Handler :: Wandle Call中受益)。
我尝试找到一种很好的方法来解决这个问题,而不要做丑陋的事情,例如首先创建一个数组,然后只指向地图中的这些对象。
我以前从未使用过移动语义,但我已经阅读了一些有关它们的信息,并认为它们可以成为我的解决方案。
但是,在阅读了此答案之后(特定于第一个示例),似乎我真的无法从使用移动语义中受益。
我无论如何都尝试过(因为为什么不……),而是这样做的:
static std::map<int, A> map = {
{42, std::move(A(1948))},
{88, std::move(A(-17))}
};
现在令我惊讶的是,MyTask的复制构造函数仍然被打电话(我在其中打印以验证),但由于某种原因,处理程序注册效果很好,我的实例很喜欢dosomething()呼叫。
我尝试更彻底地阅读有关std ::的动作,以了解那里到底发生了什么,但找不到答案。
任何人都可以解释吗?std ::移动是否会以某种方式移动指针?也许这只是导致注册正确地发生,并且没有任何 real 与移动尝试
有关谢谢
编辑:
进一步澄清我要问的内容:
我了解STD :: Move的使用并没有为在那里所做的事情做出贡献。
,但由于某种原因,它确实在地图中吸引了我的对象,以通过处理程序获得Dosomething()调用。我正在寻找这个原因
在旁注上,因为它可能属于一个不同的问题 - 是否有任何不错的方法可以以这种方式初始化地图,而不会两次创建每个对象的开销?
您的问题中的问题要多得多,但我认为我在这里理解根部问题。std::map
构造函数接收一个initialization_list
,您从此列表中调用(5)。当迭代迭代而不是移动时,将对象复制在initializer_list
中,因为initializer_list
的副本未复制基础对象。同样的影响其他std
容器,这是vector
的示例。(实时链接)
#include <vector>
#include <iostream>
struct Printer {
Printer() { std::cout << "default ctorn"; }
Printer(const Printer&) { std::cout << "copyn"; }
Printer(Printer&&) { std::cout << "moven"; }
};
int main() {
std::vector<Printer> v = {Printer{}};
}
如果您使用{std::move(Printer{})}
,您将在编译器无法轻易优化的混合物中添加另一个动作。
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 移动语义和深层/浅层复制之间有什么关系?
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 在C++中使用移动语义的正确方法是什么?
- 移动语义 c++ 单链表
- C++:使用整数移动语义
- 当变量和参数名称匹配时,移动语义构造失败
- 在 C++11 中移动语义
- 方法冗余移动调用的移动语义
- 复制省略并在返回值中移动语义
- std::元组和移动语义
- 移动语义与返回shared_ptr?
- C++具有移动语义的可变参数工厂会导致运行时崩溃