我最近尝试构建自己的共享指针和弱指针。使用 Visual Studio 编译的代码无法在 GCC (4.5.0) 中编译,并出现以下错误:
main.cpp: In function 'int main()':
main.cpp:18:27: error: no match for 'operator=' in 'wp1 = weak_ptr<int>(((const shared_ptr<int>&)((const shared_ptr<int>*)(& sp1))))'
weak_ptr.h:59:9: note: candidate is: void weak_ptr<T>::operator=(weak_ptr<T>&) [with T = int, weak_ptr<T> = weak_ptr<int>]
以下是我的代码中最重要的部分:
1)弱指针实现(注意
operator=
的声明)
#include "smart_ptr_wrapper.hpp"
#include "shared_ptr.h"
template <typename T>
class weak_ptr {
private:
// Weak wrapper implementation
typedef smart_ptr_wrapper<T> weak_ptr_wrapper;
weak_ptr_wrapper* wrapper;
private:
// Shared wrapper additional routines
void increase_reference_count() {
++(wrapper->weak_count);
}
void decrease_reference_count() {
--(wrapper->weak_count);
// Dispose the wrapper if there are no more
// references to this object
// @note This should actually lock the wrapper to
// preserve thread safety
if (wrapper->strong_count == 0 && wrapper->weak_count == 0) {
delete wrapper;
}
}
public:
// Default constructor to grant syntax flexibility
weak_ptr() : wrapper(NULL) { }
weak_ptr(const shared_ptr<T>& pointer) : wrapper(pointer.wrapper) {
increase_reference_count();
}
weak_ptr(const weak_ptr& p) : wrapper(p.wrapper) {
increase_reference_count();
}
weak_ptr& operator= (weak_ptr& p) {
// Set new reference counts
// @note If this is 'just-a-pointer', which was created
// using default constructor then our wrapper would be 'NULL'
if (wrapper != NULL) {
decrease_reference_count();
}
p.increase_reference_count();
// Set new wrapper
wrapper = p.wrapper;
return *this;
}
~weak_ptr() {
decrease_reference_count();
}
T* get() const { return (wrapper->strong_count == 0) ? NULL: wrapper->raw_pointer; }
T* operator-> () const { return get(); }
T& operator* () const { return *get(); }
// User comparison operation
operator void* () const {
return (get() == NULL);
}
};
2) main.cpp
int main() {
shared_ptr<int> sp1(new int(4));
weak_ptr<int> wp1(sp1);
// Next line can't be compiled by gcc... Why?
wp1 = weak_ptr<int>(sp1);
return 0;
}
为什么会出现这种情况?我可能很愚蠢,但我看不出这段代码有什么问题,也无法理解 GCC 的行为。如果有人能解释为什么这段代码可以编译以及为什么它在 MSVS 下工作(我的意思是,为什么一个编译器会做得很好,为什么第二个编译器会失败),我也将不胜感激。谢谢你。
更新:完整代码和编译器错误可以在这里看到 - http://codepad.org/MirlNayf
您的赋值运算符需要引用,而不是
const
引用:
weak_ptr& operator= (weak_ptr& p)
但是,表达式
weak_ptr<int>(sp1)
会产生一个临时值,它只能转换为 const
引用,因为它是一个右值。这样想:您无法修改表达式的结果,但赋值运算符要求它可以。
解决方案是像这样声明赋值运算符:
weak_ptr& operator= (const weak_ptr& p)
为什么 VC++ 接受这个超出了我的范围......也许你应该启用一些标准合规性标志。
这是因为您首先从 sp1 构造了一个新对象,然后分配了它,这不是我期望的您的预期行为。然而,根本的错误是因为赋值应该采用 const 引用。