1

I was wondering if there's a way to enforce the usage of a reference lvalue? Suppose a following scenario:

class Foo
{
public:
    Foo()
    {
        std::cout << "Foo ctor()" << std::endl;
    }

    ~Foo()
    {
        std::cout << "Foo dtor()" << std::endl;
    }
};

class FooFactory
{
public:
    Foo& create()
    {
        m_foo = new Foo();
        return *m_foo;
    }
    void destroy()
    {
        delete m_foo;
    }
private:
    Foo* m_foo;
};

int main()
{
    FooFactory factory;

    Foo& foo = factory.create();
    factory.destroy();

    return 0;
}

This code will print out the following:

Foo ctor()
Foo dtor()

Now, if I change the main() function like this:

int main()
{
    FooFactory factory;

    Foo foo = factory.create();
    factory.destroy();

    return 0;
}

The program outputs:

Foo ctor()
Foo dtor()
Foo dtor()

AFAIK, this is because there's a copy created in main() of the foo object and it is destroyed when main() goes out of scope. So, the question is: is it possible to enforce the use of Foo foo& instead of Foo foo so that there would be no copies made?

manabreak
  • 5,415
  • 7
  • 39
  • 96

1 Answers1

4

If you have a C++11 compiler, then explicitly delete the copy constructor (and optionally the copy assignment operator) for Foo

Foo(Foo const&) = delete;
Foo& operator=(Foo const&) = delete;

For a pre-C++11 compiler, declare the two private and leave them undefined

private:
  Foo(Foo const&);
  Foo& operator=(Foo const&);
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Thank you, It seems to do the trick. A small follow-up: is it necessary to do the `= delete` in C++11? What benefit does it have? – manabreak Nov 08 '14 at 06:57
  • 1
    @manabreak No, not necessary, you can use the C++03 solution with a C++11 compiler too. But with the C++03 method you can inadvertently have other member functions or `friend`s of `Foo` invoke the copy special member functions, which will result in a linker error instead of a compiler error. The C++11 way results in a compiler error which is arguably easier to understand why it occurred. – Praetorian Nov 08 '14 at 07:00