10

Note that I am working in C++03, and the deleted functions of C++11 are not available to me.

I am attempting to design a non-copyable object, and prevent the compiler from considering the implicitly-declared copy constructor on that class. This is for a unit test fixture I am developing.

Consider that I have two main objects: a core library object, Root, and a derived special-case object under test, Branch. I am trying to develop a test fixture class, Fixture which handles the minutiae of setting up & talking to the core Root object. So this is a simplified illustration of what I've built so far:

(Here is an ideone link with the same code below, except I've defined my own noncopyable)

#include <boost/utility.hpp>
#include <boost/noncopyable.hpp>

class Root
{
};

class Fixture
:
    public boost::noncopyable
{
public:
    Fixture (Root& root)
    :
        mRoot (root)
    {
    }
private:
    Root& mRoot;
};

class Branch
:
    public Root,
    public Fixture
{
public:
    Branch()
    :
        Fixture (*this)
    {
    }
};

int main()
{
    Branch branch;
}

Compiling this results in:

main.cpp: In constructor ‘Branch::Branch()’:
main.cpp:30:23: error: call of overloaded ‘Fixture(Branch&)’ is ambiguous
main.cpp:30:23: note: candidates are:
main.cpp:13:5: note: Fixture::Fixture(Root&)
main.cpp:8:7: note: Fixture::Fixture(const Fixture&)

It is not possible* to prevent the C++03 compiler from implicitly declaring a copy constructor for Fixture unless I declare at least one on my own. But even with:

class Fixture
:
    public boost::noncopyable
{
public:
    Fixture (Root& root)
    :
        mRoot (root)
    {
    }
private:
    Fixture (const Fixture&);
    Fixture (Fixture&);
    Root& mRoot;
};

...the compiler will still consider these private declarations when initializing Fixture in Branch's initialization list:

Fixture (*this)

I want the compiler to simply not consider these copy constructors.

I could do this by doing a little contorting on my own:

Fixture (static_cast <Root&> (*this))

...but I'd rather not, as it's a bit smelly to my nose and non-copy-ability is the semantics of what I'm going for by deriving Fixture from boost::noncopyable.

Is there a way to prevent the compiler from considering implicitly-declared copy constructors in this case without changing code at the call-site from:

Fixture (*this)

?


  • "It is not possible..." : Standard C++03: 12.8/4, "Special member functions":

If the class definition does not explicitly declare a copy constructor, one is declared implicitly.

4

3 に答える 3

3

C++98 でも C++11 でも、コピー コンストラクター シグネチャの存在を防ぐ方法はありません。= deleteオーバーロード セットから何かを削除することもありません。選択されている場合にのみ失敗します。

Fixture のパブリック インターフェイスをいじりたくない場合は、明示的なキャストを挿入する以外に良い考えはありません。

インターフェイスを台無しにするオプションにRootは、コピー コンストラクターの参照と区別するために by ポインターを渡したり、オーバーロードの解決のためにタグを渡したりすることが含まれます。これらについて詳しく知りたい場合は、コメントを残してください。

于 2013-06-21T15:50:44.270 に答える