Pointer members in the class

This one has lots of errors but i'm pretty sure it's just some stupid mistakes...

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
#include <iostream>

using namespace std;


struct Hello{
	Hello(int num){
        int *x = new int;
		*x = num;
	}
	public:
		void printNum(){
			cout << *x << endl;
		}
    ~Hello(){
        delete x;
    }
};

Hello *createHello(int input){
	Hello *y = new Hello;
	
	return &y;
}

int main() {
	Hello *hello = createHello(5);
	hello->printNum();
	
	return 0;
}



First error, at 'printNum', 'x' was not declared in this scope. What's my problem?

Second error, at 'Hello y = new Hello', not matching function for 'Hello'

Third error, at 'return &y', this was answered few days ago by 'Zhuge' but I still don't understand...
First error, at 'printNum', 'x' was not declared in this scope. What's my problem?


Your Hello class has no variable named 'x'.

The only 'x' in your program is in Hello's constructor... but since you declared it locally within that function it only exists inside that function and does not exist anywhere else in the program.

Remember that variables only have a life within their enclosing {braces}. As soon as the closing brace on line 10 is reached, 'x' no longer exists.

Second error, at 'Hello y = new Hello', not matching function for 'Hello'


You are trying to construct a Hello object. When this happens, one of the class's constructors is called.

You have 1 constructor: the one you declared on line 7. This constructor takes a single parameter.

On line 21 you are trying to construct an object, but you do not provide any parameters. You do not have a constructor that accepts 0 parameters, therefore you cannot construct the object that way.

You either need to provide a parameter for the constructor:
Hello* y = new Hello(input); //<- 'input' becomes the parameter

Or you need to write a constructor that accepts 0 parameters.


Third error, at 'return &y', this was answered few days ago by 'Zhuge' but I still don't understand...


1
2
3
4
5
6
7
8
9
10
11
12
13
14
int func()  // <- func has a return type of 'int'
{
    int x = 4;  //<- 'x' is of type 'int'

    return x;  // <- 'x' and the return type of the function match.  OK
}

int* foo()  // <- func has a return type of 'int*'
{
    int x = 4;  // <- 'x' is of type 'int'

    return x;  // <- ERROR, 'x' is of type int, but the function needs to return 'int*'
      // these are mismatching types, and therefore this is an error.
}



Your problem is:

1
2
3
4
5
6
7
8
Hello *createHello(int input){  //<- function returns 'Hello*'
	Hello *y = new Hello;  // <-  'y' is of type 'Hello*'
	     //  this means that '&y' is of type 'Hello**'
	
	return &y;  // <- &y is Hello**, but function requires Hello*
	    // mismatching types... ERROR
	    //   you probably meant to just "return y;"
}








Lastly, this is a terrible, terrible use of dynamic allocation. There is zero reason for 'x' to be dynamically allocated here. You are much better off with a normal, non-dynamic integer for x.

Also, passing ownership away from createHello() is questionable as well. Now it is expected that whoever calls createHello is responsible for deleting the object. Which, if you notice, you forgot to do in this code, so you are leaking memory.

It's not surprising that you forgot to delete the object. It's a very easy thing to forget. Which is exactly why you shouldn't pass ownership like this
Thanks for the answer.


Also, passing ownership away from createHello() is questionable as well

I made createHello() that you need to delete yourself because i'm learning irrlicht game engine and it has tons of stuffs like this...so i'm just trying to understand what's going on...
General rule of thumb: If you have to manually delete, you are doing something wrong.

For a createXXX style function, you're better off returning a smart pointer:

1
2
3
4
std::unique_ptr<Hello> createHello(int input)
{
    return std::unique_ptr<Hello>( new Hello(input) );
}


Now there's no passing of ownership -- the unique_ptr owns the memory and it will automatically delete it when it is destroyed. No risk of forgetting, no risk of memory leaks.
Topic archived. No new replies allowed.