C++ C++;0x move构造函数明白了
编辑:我在这里再次问了同样的问题(在解决了这个问题所指出的问题之后): 基本思想是,如果你不小心,指向可移动的东西可能会得到一些奇怪的结果C++ C++;0x move构造函数明白了,c++,c++11,move-constructor,C++,C++11,Move Constructor,编辑:我在这里再次问了同样的问题(在解决了这个问题所指出的问题之后): 基本思想是,如果你不小心,指向可移动的东西可能会得到一些奇怪的结果 < > C++移动构造函数和移动赋值操作符看起来是非常积极的事情。它们可以在复制构造函数毫无意义的情况下使用,因为它们不需要指向重复的资源 但有些情况下,如果你不小心,它们会咬你。这一点尤其重要,因为我已经看到了允许编译器生成move构造函数的默认实现的建议。如果有人能给我一个这样的链接,我会提供 因此,这里有一些代码有一些可能不完全明显的缺陷。我测试了代
< > C++移动构造函数和移动赋值操作符看起来是非常积极的事情。它们可以在复制构造函数毫无意义的情况下使用,因为它们不需要指向重复的资源 但有些情况下,如果你不小心,它们会咬你。这一点尤其重要,因为我已经看到了允许编译器生成move构造函数的默认实现的建议。如果有人能给我一个这样的链接,我会提供 因此,这里有一些代码有一些可能不完全明显的缺陷。我测试了代码,以确保它在带有
-std=gnuc++0x
标志的g++中编译。这些缺陷是什么?您将如何修复它们
#if (__cplusplus <= 199711L) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
#error This requires c++0x
#endif
#include <unordered_set>
#include <vector>
#include <utility>
#include <algorithm>
class ObserverInterface {
public:
virtual ~ObserverInterface() {}
virtual void observedChanged() = 0;
virtual void observedGoingAway() = 0;
};
class Observed {
private:
typedef ::std::unordered_set<ObserverInterface *> obcontainer_t;
public:
Observed() {}
Observed(const Observed &) = delete;
const Observed &operator =(const Observed &b) = delete;
// g++ does not currently support defaulting the move constructor.
Observed(Observed &&b) : observers_(::std::move(b.observers_)) { }
// g++ does not currently support defaulting move assignment.
const Observed &operator =(Observed &&b) {
observers_ = ::std::move(b.observers_);
return *this;
}
virtual ~Observed() {
for (auto i(observers_.begin()); i != observers_.end(); ++i) {
(*i)->observedGoingAway();
}
}
void unObserve(ObserverInterface *v) {
auto loc(observers_.find(v));
if (loc != observers_.end()) {
observers_.erase(loc);
}
}
void changed() {
if (!observers_.empty()) {
// Copy observers_ to bector so unObserve works
::std::vector<ObserverInterface *> tmp;
tmp.reserve(observers_.size());
tmp.assign(observers_.begin(), observers_.end());
for (auto i(tmp.begin()); i != tmp.end(); ++i) {
(*i)->observedChanged();
}
}
}
private:
obcontainer_t observers_;
};
class Observer : public ObserverInterface {
public:
Observer() {}
Observer(const Observer &) = delete;
const Observer &operator =(const Observer &b) = delete;
// g++ does not currently support defaulting the move constructor.
Observer(Observer &&b) : observed_(b.observed_) {
b.observed_ = 0;
return *this;
}
// g++ does not currently support defaulting move assignment.
const Observer &operator =(Observer &&b) {
observed_ = b.observed_;
b.observed_ = 0;
return *this;
}
virtual ~Observer() {
if (observed_) {
observed_->unObserve(this);
observed_ = 0;
}
}
virtual void observedChanged() {
doStuffWith(observed_);
}
virtual void observedGoingAway() {
observed_ = 0;
}
private:
Observed *observed_;
// Defined elsewhere
void doStuffWith(Observed *);
};
#如果(uu cplusplus observedgoingway();
}
}
void unObserve(observer接口*v){
自动定位(查找(v));
如果(loc!=observators_uu.end()){
删除(loc);
}
}
作废已更改(){
如果(!obsers.empty()){
//将观察员抄送给bector,以便不受影响地工作
:std::向量tmp;
tmp.reserve(观察者大小());
tmp.assign(观察者\开始(),观察者\结束());
for(自动i(tmp.begin());i!=tmp.end();+i){
(*i)->观察到的变化();
}
}
}
私人:
观察者;
};
类观察者:公共观察者接口{
公众:
观察者(){}
观察者(const Observer&)=删除;
常量观察者和运算符=(常量观察者和b)=删除;
//g++当前不支持默认移动构造函数。
观察者(观察者和b):观察者(b.观察者){
b、 观察值=0;
归还*这个;
}
//g++当前不支持默认移动分配。
常量观察者和运算符=(观察者和运算符){
观察到的;
b、 观察值=0;
归还*这个;
}
虚拟观察者(){
如果(观察到){
观察到的(这个);
观察值=0;
}
}
观察到的虚拟无效已更改(){
多斯塔夫韦(观察到);
}
虚拟void observedgoingway(){
观察值=0;
}
私人:
观察到的*观察到的;
//在别处定义
空隙度(观察*);
};
代码有很多问题
observator::observed\uuz
在默认构造函数中保持未初始化状态,从而在调用析构函数时导致未定义的行为观察者::观察者
,这使得变量多余代码有很多问题
observator::observed\uuz
在默认构造函数中保持未初始化状态,从而在调用析构函数时导致未定义的行为观察者::观察者
,这使得变量多余这是测验吗?你知道缺陷是什么吗?没有“正确的”回答,因为这需要讨论。更好的社区Wiki it,如果你想让它有机会不被关闭…@Greg Hewgill,我知道缺陷是什么。我注意到有几个人问他们知道答案的问题,因为他们认为这些问题的答案在网站上会很有用,很有教育意义.这就是这样一个问题。@Omnifarious:对于这样一个“我知道答案,你知道吗?”这类问题要想有用,就必须足够具体,让能够从中学习的人能够真正找到它。目前这类问题太开放了。如果你想回答别人还没有问过的问题,那么就把问题具体化,让想问的人能够找到它。@jalf,这是有道理的。我投了赞成票结束这个问题,我将修改它,并以不同的方式提问。这是一个测验吗?你知道缺陷是什么吗?没有“正确的”回答,因为这需要讨论。更好的社区Wiki it,如果你想让它有机会不被关闭…@Greg Hewgill,我知道缺陷是什么。我注意到有几个人问他们知道答案的问题,因为他们认为这些问题的答案在网站上会很有用,很有教育意义.这就是这样一个问题。@Omnifarious:对于这样一个“我知道答案,你知道吗?”这类问题要想有用,就必须足够具体,让能够从中学习的人能够真正找到它。目前这类问题太开放了。如果你想回答别人还没有问过的问题,那么就把问题具体化,让想问的人能够找到它。@jalf,这是有道理的。我投了赞成票关闭此问题,我将修改它并以不同的方式提问。叹气谢谢。您已经强调了与我所想的内容无关的足够多的问题,我认为我应该删除此问题并重新开始。不过,您有我所想的问题之一。#3.叹气谢谢。您已经强调了与我所想的内容无关的足够多的问题我对t的想法感到惊讶