avoid copy by value when initializing reference

153 Views Asked by At

I have a function interface:

struct iFace {
  virtual Type& getType() = 0;
}

and the idea is to retrieve it like:

iFace& iface = getIface();
Type& type = iface.getType();

however, i occassionally i do a mistake and write:

Type type = iface.getType();

which copies by value, which is what i want to avoid. However when i make such mistakes, the compiler doesn't issue a warning because its legal syntax. I would like to trigger a compile-time error for this, Question what are my alternatives?

i thought about declaring a copy constructor but not defining it anywhere, causing a link-time error if it's used, but then i won't be able to use copy constructor in ANY situation, which is less than desiderable

2

There are 2 best solutions below

4
On BEST ANSWER

Make iFace noncopyable by putting the copy constructor and assignment operator under "private". Then provide an explicit Copy method.

class Type {
public:
  virtual Copy(Type& dest) = 0;
private:
  Type (const Type &) {assert(false)}
  Type & operator=(const Type &)  {assert(false)}
}

You can also use boost noncopyable to do the same thing (its implemented as above).

So if you wanted your code to copy, you would do

Type& type = iface.getType();
Type typeCpy;
type.Copy(typeCpy);

As an aside -- I'd add that if you're doing this because of performance concerns, are you certain the optimizer doesn't get rid of the temporary copy for you?

0
On

Returning a pointer seems reasonable here, but if confusing ownership worries you you could return a wrapper around the reference.

struct Class {
    struct Ref {
        Ref(Class& c_) : c(c_) { }
        Class Clone() { return c; }
        // overload -> to provide access to c
      private:
        Class& c;
    };
};

The original class can copy as normal, but the reference you have to do explicitely. I'm not enthusiastic about the idea (I would think less of a user who didn't realize how copy semantics work than one who accidently held onto one of these too long) but theoretically it is doable.