vendredi 4 décembre 2015

How to prevent accidentally calling a mutating function on a non-const object?

Suppose we have an Object obj of type myType, and we would like to pass it to function Foo, which returns us some valuable information about obj. function Bar is where obj is declared and from which Foo is being called like this:

void Bar ()
{

myType obj; //default constructor

string valuableInfo = Foo(obj); 

//do other stuff
//...

} //end of Bar()

This snippet of code of course does not say much about whether Foo takes obj as a reference or as value, and whether or not Foo modifies obj in any way.

of course if Foo takes obj as value or const reference, we wont have any issues.

string Foo (const myType & input); //this is fine 
string Foo (myType input); //so is this

but we are not guaranteed this! the function signature could very well be

string Foo (myType & input); //asking for trouble!!

but it is awfully inconvenient to check the signature of every function we would want to pass obj to, so how can we specify that we want to only pass our object to functions that promise not to modify it?

of course one approach is to declare obj as const, but the problem with this approach is that we lose flexibility. what if we want to modify obj in Bar() after calling Foo(obj)?

void Bar ()
{

const myType obj; //default constructor

string valuableInfo = Foo(obj); //compiler will complain if Foo's signature doesnt match

//we can't modify obj here :(
//...

} //end of Bar()

The obvious but bad solution is to do this:

void Bar ()
{

myType obj; //default constructor

const myType immutableObj {obj}; //copy ctr call
//this is expensive and not recommended if obj is big! want to avoid

string valuableInfo = Foo(immutableObj); //will get the valuable Info risk free
// compiler will complain if Foo has inappropriate signature

//do other stuff
//...

} //end of Bar()

so What is the best solution here? is there a way to statically assert that Foo is non invasive to the object we pass in? can we temporarily make obj const (without having to create a new const object) or something to that effect?

Aucun commentaire:

Enregistrer un commentaire