C++0x:当一个临时对象等于另一个临时对象时
C++0x: when a temporary object equals another temporary object
struct F
{
private:
int* data;
public:
F( int n )
{
data = new int;
*data = n;
}
F( int* p )
{
data = p;
}
F& operator=( const F& f )
{
*data = *(f.get_data());
return *this;
}
F& operator=( F&& f )
{
delete data;
data = f.data;
f.data = nullptr;
return *this;
}
F& operator=( int n ) { *data = n; return *this; }
F operator()()
{
F cpy_f( data );
return std::move( cpy_f );
}
int* get_data() const { return data; }
};
int main()
{
F f( 12 );
F g( 14 );
f() = g();
cout << *(f.get_data()) << endl;
}
在此示例中,f()
和 g()
分别返回一个临时对象,因此f()=g()
生成临时对象的表达式等于临时对象。如果正确复制该值,我本以为答案是 14。但是,它不是调用复制赋值,而是调用移动赋值!结果,答案不是14。
这让我真的很困惑。尽管从f()
和g()
返回的对象是临时的,但它们与其他一些对象共享一些信息。这意味着临时对象可能很快就会为共享信息做一些工作。因此,我认为语义上调用复制分配是正确的行为。
附言。我的编译器是 g++4.7 20110430
您的operator()
返回一个值,而不是引用或指针。因此,它返回一个临时的。临时隐式绑定到 &&优先(它们是唯一这样做的类型(。因此,如果有移动分配运算符供他们使用,他们将更愿意使用它。
你的问题是,当你在operator()
函数中这样做时,你停止了做合理的事情:
F cpy_f( data );
采用指针的 F
的构造函数使用指针值本身,从而有效地采用指针。此时,您现在有两个指向相同数据的F
实例。
如果这是您想要合理的,那么您不能让移动分配运算符删除指针。您需要协调这样一个事实,即您可以有两个指向同一事物的F
实例。两者需要共享指针的所有权。所以。。。你打算怎么做?
我建议完全摆脱这个构造函数。它只会给你带来更多的问题。我还建议使用std::unique_ptr<int> data;
而不是裸指针。这样,您就不必编写移动构造函数/赋值运算符(尽管您确实需要复制构造函数/赋值运算符(。
您正在创建一个实例,该实例具有指向相同位置的指针。使用 F::operator()
创建的实例不共享指针本身。
f()=g()
等效于 f((.operator=(g(((,并且g()
创建一个临时实例,因此调用移动分配是正确的。
问题是f
在执行f()=g()
后有一个悬空的指针。 创建临时实例f()
,它会删除移动分配运算符中的指针,但f
本身仍然具有指向已删除位置的指针。
我不确定你在用这些复杂的代码做什么,但你最好用std::shared_ptr
或其他东西重写代码。
附言返回实例时不需要std::move
。如果未关闭这些功能,则编译器具有 RVO 功能。
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 检查哪个对象调用了另一个对象的对象方法
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 如何在qt中将信号和插槽与另一个对象连接 --解决了
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- Qt:从另一个窗口访问公共对象
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- C++:将初始化的对象传递给另一个类的构造函数;需要不必要的构造函数吗?
- 将另一个类的对象传递到当前类C++的构造函数中(不是成员初始化)
- 结束另一个线程中使用的对象的生存期
- 如何将我编写的对象传递到另一个类的构造函数中?
- C++0x:当一个临时对象等于另一个临时对象时
- 删除对象(另一个..)时双重释放或损坏
- 当临时返回对象立即分配给另一个对象时调用复制构造函数