Optional argument passed by reference
-
Also I write such things:
void DoSomething(void) { tData &data(GetData()); if(&data==NULL) return; //GetData returned NULL data.a=1.0; data.b=... }I can rewrite it in more "correct" form, but like dots (
.) and not like arrows (->) :void DoSomething(void) { tData *data(GetData()); if(data==NULL) return; //GetData returned NULL data->a=1.0; data->b=... }
-
SAn schrieb:
But I do not use the reference until I check that it is actually
!=NULL. Is this still unsafe ??Dereferencing a null pointer is in itself undefined behaviour, whatever happens after doesn't matter. If an argument is optional, either using a dummy object as shown or a pointer parameter should be preferred. Using an overloaded function would be sufficient as well.
SAn schrieb:
camper schrieb:
How to make
dataSizeconst in the first case of call? :tDataSize dataSize; //How to make this const? tData const *const data(GetData(dataSize));please rephrase.
I just want
dataSizeto be protected from further modification after correct size of data stored in it.There is no way to do that. Your function doesn't really (logically) take a parameter, rather it returns two values. The function should return a pair of values - not needing one of the return values is not a problem then. A reference to boost.tuple is in order.
std::pair<tData*,tDataSize> GetData(); tData* foo = GetData().first; // if we don't need size tDataSize bar = GetData().second; // if we don't need the pointer boost::tie(foo,bar) = GetData(); // if we want both std::pair<tData*,tDataSize> foobar = GetData(); // might be a little bit awkward // C++0x auto foobar = GetData(); // would solve that problem
-
SAn schrieb:
But I do not use the reference until I check that it is actually
!=NULL. Is this still unsafe ??As camper said before what you are doing is not safe. References always must be bound to valid objects, NULL doesn't point to any one. Use pointers to distinguish between valid and invalid objects, not references.
But this doesn't seem to be your real problem.SAn schrieb:
if(&size != &tempDataSize) //Just to illustrate how to make detection of optional argument, so I can skip it calculation for speed-upThis is not good practise. Use overloaded functions if you often need optional function arguments passed by reference. Write redundant code in seperate functions. Combine this with strategy pattern or something like that.
Sometimes a const reference may be sufficient for your needs.
tData* GetData(const tDataSize& size = tDataSize())Remember, temporary objects can only be bound to references to const objects.
SAn schrieb:
I just want
dataSizeto be protected from further modification after correct size of data stored in it.This is not possible at compile time.
-
groovemaster schrieb:
Lie when your wife is waking. Lie when your belly's aching. Lie when you know she's faking. Lie, sell shoes, and lie.
C-Casts in C++ stinken - bastaThey do make lying that much easier though...
-

-
How much new information for me!
std::pairis standard thing in C++ ??
I found it in<utility>in my system, but I do not know if it will be available on other platforms and if it will be understandable by users of my library. For example, I learned about it a few minutes ago.
-
everything in namespace std is standardized and plattform independent (mostly, in the end it depends upon how standard compatible the implementation for the platform is)
-
SAn schrieb:
std::pairis standard thing in C++ ??yes.
Another way to deal with this particular case would be to think of the return value as a view into an array allocated elsewhere. boost has the means for that as well, Boost.MultiArray
for exampleconst_multi_array_ref<tData,1> GetData(); // a 1-dimensional array, the ref suffix denotes that it refers to storage allocated elsewhere const_multi_array_ref<tData,1> data = GetData(); tData const* ptr = data.origin(); // if we absolutely have to have a pointer, // since multi_array is a proper STL sequence chances are that you won't need it tDataSize size = data.size();
-
groovemaster schrieb:
SAn schrieb:
if(&size != &tempDataSize) //Just to illustrate how to make detection of optional argument, so I can skip it calculation for speed-upThis is not good practise. Use overloaded functions if you often need optional function arguments passed by reference. Write redundant code in seperate functions. Combine this with strategy pattern or something like that.
What is "strategy pattern" and how to use it in this case?
-
Hi SAn,
old thread

The strategy pattern is a design pattern. You can find out more about design patterns here.
The strategy pattern is useful if you have an algorithm or more general code that needs different implementations (strategy) at a certain place depending on the input or your needs. You simply abstract these implementations in an interface. It is like a kind of "macro parameter".
I don't know if this will be really helpful for your application due to the little code you posted. But it looks a bit like. Just take it as a suggestion for better designs.