哪个更好:一个谎言的复制构造函数或一个非标准的复制构造函数?

Pau*_*ulH 4 c++

我有一个包含不可复制句柄的C++类.但是,该类必须具有复制构造函数.所以,我已经实现了一个将句柄的所有权转移到新对象(如下所示),

class Foo
{
public:
    Foo() : h_( INVALID_HANDLE_VALUE )
    {
    };

    // transfer the handle to the new instance
    Foo( const Foo& other ) : h_( other.Detach() )
    {
    };

    ~Foo()
    {
        if( INVALID_HANDLE_VALUE != h_ )
            CloseHandle( h_ );
    };

    // other interesting functions...

private:

    /// disallow assignment
    const Foo& operator=( const Foo& );

    HANDLE Detach() const
    {
        HANDLE h = h_;
        h_ = INVALID_HANDLE_VALUE;
        return h;
    };

    /// a non-copyable handle
    mutable HANDLE h_;
}; // class Foo
Run Code Online (Sandbox Code Playgroud)

我的问题是标准的复制构造函数采用const引用,我正在修改该引用.所以,我想知道哪个更好(以及为什么):

  1. 非标准的复制构造函数: Foo( Foo& other );

  2. 一个'谎言'的复制构造函数: Foo( const Foo& other );


编辑:

DuplicateHandle()仅适用于特定类型的句柄.这不是其中的一个.无法复制,复制或克隆此句柄.

有几个人指出我错误地认为它是一个非标准的复制构造函数并且这样std::auto_ptr做.我认为这可能是要走的路.但是,每当我使用类时,当我使复制ctor取非const值时,我最终会收到警告.例如:

namespace detail {
    class Foo { ... };
};

class Buzz
{
public:
    typedef detail::Foo Fuzz;

    Fuzz bar() const { return Fuzz(); }; // warning here
};

warning C4239: nonstandard extension used : 'argument' : conversion from 'Foo' to 'Foo &'
1> A non-const reference may only be bound to an lvalue; copy constructor takes a reference to non-const
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议我应该对他们做些什么?


EDIT2:

每个人似乎都在引导我走向std::auto_ptr<>做事的方法.所以,我看了那里,它使用一个中间结构来解决我在第一次编辑中描述的问题.这是我提出的解决方案.

class Foo;

struct Foo_ref
{
    explicit Foo_ref( Foo& other ) : ref_( other ) {};
    Foo& ref_;
private:
    const Foo_ref& operator=( const Foo_ref& );
}; // struct Foo_ref

class Foo
{
public:
    Foo() : h_( INVALID_HANDLE_VALUE )
    {
    };

    // transfer the handle to the new instance
    Foo( Foo_ref other ) : h_( other.ref_.Detach() )
    {
    };

    ~Foo()
    {
        if( INVALID_HANDLE_VALUE != h_ )
            CloseHandle( h_ );
    };

    operator Foo_ref()
    {
        Foo_ref tmp( *this );
        return tmp;
    };

    // other interesting functions...

private:

    /// disallow assignment
    const Foo& operator=( const Foo& );

    HANDLE Detach()
    {
        HANDLE h = h_;
        h_ = INVALID_HANDLE_VALUE;
        return h;
    };

    /// a non-copyable handle
    HANDLE h_;
}; // class Foo
Run Code Online (Sandbox Code Playgroud)

它在警告级别4上干净地编译并且似乎有效.请让我知道它是否比我原来的帖子更不负责任.

Ter*_*fey 6

两者都很可怕.如果您的类具有不可复制的成员变量,那么您的类是不可复制的.

如果你的类是不可复制的是非常不可接受的,那么解决一个问题就是拥有一个指向"状态"类/结构的共享指针来存储不可复制的对象(它本身是不可复制的),但你的类可以通过标准复制共享指针复制构造函数.