我想创建一个类型,它可以用另一个类型的赋值来初始化,但不能被复制。这个想法类似于作用域智能指针的想法,因为我希望这种类型的对象在其生命周期内拥有资源,但我也希望能够使用赋值语法。所以在概要中,这就是我想要的:
T x = new U; // allowed
T y(new U); // allowed
T z = x; // not allowed
T x2(x) // not allowed
这是我到目前为止尝试过的...
#include <boost/noncopyable.hpp>
class U {};
class T : boost::noncopyable {
public:
T(U *p) : p_(p) {
}
~T() {
delete p_;
}
operator bool() const { return p_ != 0; }
private:
U *p_;
};
int main() {
T x = new U; // allowed
T y(new U); // allowed
//T z = x; // not allowed
//T x2(x) // not allowed
}
不幸的是,这会导致错误:
$ g++ test.cc -o test /usr/include/boost/noncopyable.hpp: In copy constructor 'T::T(const T&)': /usr/include/boost/noncopyable.hpp:27:7: error: 'boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)' is private test.cc:6:30: error: within this context test.cc: In function 'int main()': test.cc:20:12: note: synthesized method 'T::T(const T&)' first required here
注意:C++11 的移动功能对我来说不是一个选项,因为它必须能够使用不支持 C++11 的相对较旧版本的 gcc 进行编译。
由于缺少 C++11 支持,我不确定是否有“好的”解决方案。但我想我会问。
最佳答案
如果我对评论的理解是正确的——你想要这样的东西:
U* create_T() { return new U; }
if (T t = create_T())
{
// do something with t
}
这里的问题,已经在评论中提到:这个语法 T t = u
只是调用复制构造函数。如果 u 是 T
类型,它等同于:T t(u)
。如果 u
像您的示例一样,是另一种可转换为 T
的类型(此处为 T::T(U*)
),那么它实际上是这样的:T t(T(u))
。所以在这里你有编译器提示的复制构造函数。
没有解决方案,因为这不是有效的 if
语法:
if (T i(create_T())) {}
但是,如果没有好的建议,我不会写所有这些;)
您可以忘记使用此语法的复制构造函数的问题:
if (U* u = create_T()) {
T t(u);
....
}
顺便说一句,std::auto_ptr
与您的 T
类型有同样的问题。只需将显式添加到您的 T(U*)
构造函数中,您就会看到与 auto_ptr
的相似之处:
class U {};
class T : boost::noncopyable {
public:
explicit T(U *p) : p_(p) {
}
~T() {
delete p_;
}
private:
U *p_;
};
int main() {
T x = new U; // allowed
T y(new U); // allowed
std::auto_ptr<U> a = new U;
std::auto_ptr<U> b(new U);
}
结果:
prog.cpp:25: error: conversion from ‘U*’ to non-scalar type ‘T’ requested
prog.cpp:27: error: conversion from ‘U*’ to non-scalar type ‘std::auto_ptr<U>’ requested
这是我的 ideone学习...
关于c++ - 创建一个可以用赋值初始化但不可复制的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12269438/