How do I store a returned class?

Pages: 12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
auto test(){

   class yo {
       public:
       int a = 2;	
   };

   yo yo1;
   return yo1;

}


int main(){
	
   ? = test();

}
Last edited on
auto var = test();

I think. That should work, but now you have to do a bunch of work to figure out what var IS so you can use it, assuming it could be one of many things (else why do this?).
I tested a similar example with auto and it does work, for whatever that is worth.


Last edited on
I wanted a unique object for every request to the server. Didn't know how to increment new unique object names like this: "yo yo2, yo yo3" and so on. So this seems to work good.

Maybe you know something else?

Last edited on
You could store your individual objects in a container (or an array),
1
2
3
4
5
6
7
#include <vector>
    ...
   std::vector<yo> v_yo;
    ...
    v_yo.push_back( test() );
    ...
    int my_var = v_yo[idx].a;

Last edited on
Thanks man, that's also good.
I think the big problem here is that the definition of class yo is local to function test. So there's no way in main() to access the members of the return value.

This is certainly a pathological case!

Put the declaration of class yo at the top of the program and don't go auto-happy unless there's a good reason:
1
2
3
4
5
6
7
8
9
10
11
12
13
class yo {
public:
    int a = 2;
};

yo test(){
   yo yo1;
   return yo1;
}

int main(){
    yo bar = test();
}

I agree^^^
local classes seem like a bad idea to me. But if I bother to make a class, I expect to reuse it, so maybe that is a personal disconnect / style thing.
dhayden:

Why is auto bad? It looks hot ;) Doesn't it just find the right type for me?
auto has its uses. For example:

Using it to declare an iterator to a C++ container, like std::string or std::vector, is a lot less error-prone (and less typing) with auto.

Indiscriminate use can make understanding the type of a variable harder for a programmer.

auto is a useful part of the language, just don't over-do it. :)
The code below doesn't work. (error: 'request' was not declared in this scope). But when I put "cout << request.length;" within the if statement it works.

get_request_info() returns class/object.


1
2
3
4
5
6
7
8
9
10
11
12
13
void function() {


     if(initial_message) {
		
           request_info request = get_request_info(recvbuf, &iResult);

     }

      cout << request.length;


}
Last edited on
request is only visible within the if statement.

https://www.learncpp.com/cpp-tutorial/4-1a-local-variables-and-local-scope/
Thanks Furry :) So now I have another question regarding how to return a class/object.

get_request_info() creates a new object of an existing class(called request_info), then changes some values of the object, without messing up the original class.

So at some point within get_request_info() this is happening: request_info request, then request gets returned.

But the calling function also creates "request_info request" so that it can store the object returned from the function(get_request_info). Im guessing when creating an object from a class, the content of the class gets copied to the new object? (Or something similar) If so, then it would be better if I somehow could create an empty object instead that can hold the return value of get_request_info()

But how?

Last edited on
How do I store a returned class?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

class Test
{
public:
   int a { 5 };
};

Test func()
{
   Test b;

   return b;
}

int main()
{
   Test c = func();

   std::cout << c.a << '\n';
}

5

I'll use your example to describe my case

This part: Test c = func(), happens within a if statement for me. So I cant access the values after the if statement/curly braces, and that's the problem.

So I had to do "Test c;" in the global scope before the if statement, then "c = func()" within the if statement

So basically, im first creating a massive object from a class(Test), with values that I dont need, just to able to store the class/object returned from the function.

As mentioned before, I use "Test" just as an example, but in my code it's a class filled with a lot of data.

I wonder if it's not possible just to create an empty object in the beginning of the global scope, that I later can use to store the object returned from the function?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

class Test
{
public:
   int a { 5 };
};

Test func()
{
   Test b;

   b.a = 125;

   return b;
}

int main()
{
   Test c;

   std::cout << c.a << '\n';

   if (/* some condition is */ true)
   {
      c = func();
   }

   std::cout << c.a << '\n';
}

5
125

Now, if you truly meant global scope:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

class Test
{
public:
   int a { 5 };
};

Test c;

Test func()
{
   Test b;

   b.a = 125;

   std::cout << "In func: " << c.a << '\n';

   return b;
}

int main()
{
   std::cout << c.a << '\n';

   if (/* some condition is */ true)
   {
      c = func();
   }

   std::cout << c.a << '\n';
}

5
In func: 5
125
Last edited on
You dont hear me brother.

When you do: Test c; You get a object(A) with all the values from class Test. Doesn't that feel unnecessary (to get all those values, that you dont care about), just to able to assign object(B) to it later from the function call.

So let's try again. How do I create an empty object(A), or something else that later can hold object(B)
There is no such thing as an "empty" object. Some types might have an empty state (e.g. a string is empty if the length == 0) but what that means for your class is something you have to decide when designing the class.
Last edited on
How do I create an empty object(A), or something else that later can hold object(B)

Which is not what your posted code does. Your class constructs an object with a set data member value. It is not empty.

Use a C++ container, such as a std::vector, As was suggested earlier.

http://www.cplusplus.com/reference/vector/vector/

The default constructor for a std::vector constructs an empty container. It initially has no elements.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <vector>

class Test
{
public:
   int a { };
};

Test func()
{
   // create a local temp
   Test b;

   // give it some value other than the default
   // it can be the result of a loooooong calculation
   b.a = 125;

   return b;
}

int main()
{
   // construct an empty container
   std::vector<Test> c;

   std::cout << "The Test vector contains " << c.size() << " elements.\n";

   if (/* some condition is */ true)
   {
      c.push_back(func()); // add the result of the function to the vector
   }

   if (c.empty()) // empty means no elements
   {
      std::cout << "The Test vector is empty.\n";
   }
   else
   {
      std::cout << "The Test vector contains " << c.size() << " elements.\n";

      std::cout << "Test vector contains: " << c.at(0).a << '\n';
   }
}

Change line 29's if condition from true to false, your vector is still empty. Nothing is ever pushed back.

A std::vector is a dynamic container, it can be sized and resized at run-time as needed.
If not empty, then as close as you can get would be good. I guess I can create an object from a random class(non values added), that I can use to store the returned object from the function.

But is there a way where I can create an object(without getting it from a class), that later can hold another object?


Well, one alternative is to use std::optional.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <optional>

...

int main()
{
	std::optional<Test> c;
	
	if (/* some condition is */ true)
	{
		c = func();
	}
	
	if (c.has_value()) // or simply 'if (c)'
	{
		std::cout << c->a << '\n';
	}
}
Last edited on
Pages: 12