My Class Goes Out Of Scope? (wxWidgets)

I'm in my second semester, and have been assigned this monster project. The sources are 13 separate files. For now i'll just post where i think the problem is, but can attach more as necessary.

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
 case TRIANGLE:
   if (event.LeftDown()) {
      if (corners == 0) { // first click
         Drawing::Triangle triangle;
         triangle.setFirstPoint(x, y);
         corners++;
         Refresh();
      }
   } // first vertex
   if (event.LeftDown()) {
      if (corners > 0) { // second click
         triangle.setSecondPoint(x, y);
         corners++;
         Refresh();
      }
   } // second vertex
   if (event.LeftDown()) {
      if (corners > 1) { // third click
         triangle.setThirdPoint(x, y);
         triangleVector.push_back(triangle);
         corners++;
         Refresh();
      }
   } // third vertex
break;


Explanation: The goal here is to draw a triangle after the user clicks three times. event.LeftDown() is provided by wxWidgets and goes true when the mouse left button is pressed. The Triangle class setFirstPoint(), etc. are meant to collect those clicks so that lines can be drawn between the appropriate points. However, what i currently have doesn't compile:

$ g++ `wx-config --cppflags` -o Project *.cpp `wx-config --libs`
DrawingWindow.cpp:143:5: error: use of undeclared identifier 'triangle'
                                triangle.setSecondPoint(x, y);
                                ^
DrawingWindow.cpp:151:5: error: use of undeclared identifier 'triangle'
                                triangle.setThirdPoint(x, y);
                                ^
DrawingWindow.cpp:152:30: error: use of undeclared identifier 'triangle'
                                triangleVector.push_back(triangle);
                                                         ^


So how can i rearrange the code to collect the three clicks in the same scope? Note: i tried moving the Drawing::Triangle line out of the if block, just under the case statement but that causes another problem.
Last edited on
The issue is that you have a variable initialization inside your switch/case. However, switch/case statements are built using jump tables (usually) so you are not allowed to do this:

1
2
3
4
5
6
7
8
9
10
11
12
switch(arg) {
  case 1:
    //create and init x
    int x = 2;
    x++;
    break;
  case 2:
    //we are still  in the same scope, so x exists here!
    x++;
    //but this is invalid, because we could skip the creation of x
    break;
}


To fix this, simply create a new scope inside your case area:
1
2
3
4
5
6
7
8
9
10
11
switch(arg) {
  case 1:
    {
      int x = 2;
      x++;
    }
    break;
  case 2:
    //x++; now x doesn't exist here, it is created and destroyed in the scope we created
    break;
}
Last edited on
Try surrounding all the individual switch cases with there own brackets {}.

Thinking about it, pretty sure the brackets will fix both problems. Let me know if it doesn't.
@firedraco: thanks for the in-depth explanation, but i don't see how it applies to my situation. The code i posted above is all one case. What separates line 5 [which works] from line 12 is that they are in different 'if' blocks. Does my object go out of scope at the end of the first if block?
I put in the braces, but still get the same error.

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
	case TRIANGLE: {
		if (event.LeftDown()) {
			if (corners == 0) { // first click
				Drawing::Triangle triangle;
				triangle.setFirstPoint(x, y);
				corners++;
				Refresh();
			}
		}	// first vertex
		if (event.LeftDown()) {
			if (corners > 0) { // second click
				triangle.setSecondPoint(x, y);
				corners++;
				Refresh();
			}
		}	// second vertex
		if (event.LeftDown()) {
			if (corners > 1) { // third click
				triangle.setThirdPoint(x, y);
				triangleVector.push_back(triangle);
				corners++;
				Refresh();
			}
 		}	// third vertex
 	}	// TRIANGLE
		break;
firedraco was demonstrating that the triangle doesn't exist after the code block it was defined in ends. Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
case TRIANGLE:
   if (event.LeftDown()) {
      if (corners == 0) { // first vertex
         /*Drawing::Triangle*/ triangle; //declare the triangle somewhere it won't be destroyed to early.
         triangle.setFirstPoint(x, y);
         corners++;
         Refresh();
      }
      else if (corners == 1) { // second vertex
         triangle.setSecondPoint(x, y);
         corners++;
         Refresh();
      }/
      else if (corners == 2) { // third vertex
         triangle.setThirdPoint(x, y);
         triangleVector.push_back(triangle);
         corners++;
         Refresh();
      }
   } 
break;
Last edited on
For the record, this is what compiled:

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
	case TRIANGLE: {
		Drawing::Triangle triangle;
		if (event.LeftDown()) {
			if (corners == 0) { // first click
				Drawing::Triangle triangle;
				triangle.setFirstPoint(x, y);
				corners++;
				Refresh();
			}
		}	// first vertex
		if (event.LeftDown()) {
			if (corners == 1) { // second click
				triangle.setSecondPoint(x, y);
				corners++;
				Refresh();
			}
		}	// second vertex
		if (event.LeftDown()) {
			if (corners == 2) { // third click
				triangle.setThirdPoint(x, y);
				triangleVector.push_back(triangle);
				corners++;
				Refresh();
			}
 		}	// third vertex
 	}	// TRIANGLE
		break;


So, both declaring the triangle outside of the 'if' block, && the extra set of braces suggested by Militie. Neither fix was sufficient alone.
Topic archived. No new replies allowed.