views:

105

answers:

7

Hello,

let's say I want my users to use only one class, say SpecialData. Now, this data class would have many methods, and depending on the type of data, the methods do different things, internally, but return externally similar results. Therefore my wanting to have one "public" class and other "private", child classes that would change the behavior of methods, etc...

It would be amazingly more simple for some types of data that need to be built to do something like this:

SpecialData& sm = SpecialData::new_supermatrix();

and new_supermatrix() would return a SuperMatrix instance, which inherits from most behaviors of SpecialData.

my header:

static SpecialData& new_supermatrix();

my cpp:

SpecialData& SpecialData::new_supermatrix()(){
  return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
}

The problem is, I get this error, which is probably logical due to the circumstances:

invalid initialization of non-const reference of type ‘SpecialData&’ from a temporary of type ‘SpecialData’

So, any ideas?

A: 

You need to actually use the new operator. The creation you get by return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); allocates the object on the stack, which is cleaned up when the function returns (which it is doing in the same line). Using new causes it to be allocated on the heap.

Donnie
+2  A: 

Simple answer - you can't use references like that. Your new_supermatrix function returns a nameless temporary value which you try to bind to a non-const reference - C++ only allows such values to be bound to const references. If you want to write functions like this, you need to make them return a pointer to a dynamically allocated object, or stick with returning a value, but assign the return value to another value in the calling code.

anon
+1  A: 

This code has several problems. First of all, you probably want to use pointers here instead of references. Returning a reference to an object created on the stack like you do in your new_supermatrix will lead to a crash almost immediately. It needs to be allocated with new and passed back as a pointer if that's what you want but I'm not exactly sure what you're trying to do. But anyway, this is what's causing your error, you're returning a reference to a temporary variable.

bshields
A: 

In your method, you can use a static:

SpecialData& SpecialData::new_supermatrix()(){
  static SuperMatrix supermatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
  return supermatrix;
}
strager
A: 

You must not return a reference to a temporary/local object.

This and many other common errors-to-be-avoided are explained in Meyers' book, Effective C++.

ChrisW
A: 

You're returning a reference to a temporary object, which is bad news, since once your method exits, the object doesn't exist anymore.

Read up on creational design patterns. The one that looks closest to what you want to do is the Factory Method pattern.

JohnMcG
+1  A: 

Well, you've got three choices:

a) You want to have only one instance of SuperMatrix anyway. Then go for the static function member route as has already been suggested.

b) You want to create multiple instances. Then you have to return a pointer instead of references and create the objects with with new (i.e. return new SuperMatrix(...).

c) As an alternative to option b, you can also return merely an object, i.e.

SpecialData SpecialData::new_supermatrix()(){
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
}

However, this requires a (deep-)copy operator (the default one won't suffice more often than not), and it means that the object is created on the stack, then copied and that copy is being returned. The good thing is, this won't leak memory if you don't actually receive the result into a variable. The bad thing is, if the object is very large, this can be very memory- and time-consuming.

Whatever you are going to do with it, these solutions are mutually exclusive, both technically and logically. ;)

Mephane