Manux
Manux

Reputation: 3713

Create an instance from a static method

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?

Upvotes: 1

Views: 5777

Answers (7)

Mephane
Mephane

Reputation: 2022

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. ;)

Upvotes: 3

JohnMcG
JohnMcG

Reputation: 8805

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.

Upvotes: 0

ChrisW
ChrisW

Reputation: 56113

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++.

Upvotes: 0

anon
anon

Reputation:

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.

Upvotes: 2

strager
strager

Reputation: 90012

In your method, you can use a static:

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

Upvotes: 0

bshields
bshields

Reputation: 3593

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.

Upvotes: 1

Donnie
Donnie

Reputation: 46913

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.

Upvotes: 0

Related Questions