This page is a guide to how parameters should be passed in C++.
| type * | Callee takes ownership. |
| type & | Callee will modify in-place. |
| const type & | Copying is expensive. |
| type | Copying is not expensive (primitive types, copy-on-write objects). |
| type * | Passing a C-style array which should be modified by callee. |
| const type * | Passing a C-style array which should NOT be modified by callee. |
There follows a sketch of the declaration of a class with many methods, each handling different parameter types, passed in different ways. Look at each example below and refer back to the declaration of class G, to see the parameter declaration relevant to the call being made.
class G
{
...
void takeOwnership(Foo *);
void modify(Foo &);
void lookAt(const BigFoo &);
void doWhatYouLikeWith(int i);
void doWhatYouLikeWith(CopyOnWrite c);
void lookAt(const char *);
void fill(char *, unsigned int);
};
Create object, let callee take ownership.
Foo * f = new Foo;
g.takeOwnership(f);
After the call, you should probably forget about f, so a better way, when possible, is the following:
g.takeOwnership(new Foo);
Let g modify f.
Foo f;
g.modify(f);
BigFoo objects are too big to pass by value.
BigFoo bf;
g.lookAt(bf);
No point trying to be more efficient with primitive types.
int i;
g.doWhatYouLikeWith(i);
Again, no point trying to be more efficient. Copy-on-write objects only have their internal reference count incremented when ‘copied’. We could pass as const &, but then if the callee wanted to modify the passed object (common!), they’d have to copy it first, so that’s pointless.
CopyOnWrite cow;
g.doWhatYouLikeWith(cow);
Using a C-style array. We don’t want g to modify our s.
const char * s = "Hello, world!";
g.lookAt(i);
Using a C-style array again. This time we do want g to modify it.
const unsigned int bufSize = 4096;
char * buf = new char[bufSize];
g.fill(buf, bufSize);