and after the selection attempt to access the combatant1 object and get a "not declared in this scope" error in the compiler. So, I am pretty certain that the compiler cant track where the object was declared because it is nested in an 'if' statement, but I am not sure how to properly create an object that might be one of a number of different possible children in a way the compiler will like.
#include "The_Awesome_Combatant_Types.h"
#include <memory>
int main(){
//Let ranger and warrior be children of a common parent combatant_type
std::shared_ptr<combatant_type> combatant1(nullptr);
int menu(0);
//Modify menu...
switch(menu){
case 1:
combatant1.reset(new ranger());
break;
case 2:
combatant1.reset(new warrior());
break;
//Blah blah blah...
}
//Blah blah blah...
combatant1->do_something(); //Virtual function from combatant_type that
// is overridden in ranger and/or warrior
//Blah blah blah...
return 0;
}
It is not that the compiler can't "track" it, the object no longer exists.
You've got two choices:
- declare the object before the if block (check out: inheritance, polymorphism, strategy pattern)
- don't refer to the object after the if block
Daleth, hilariously, polymorphism is next week in the class that I am doing this for. I was trying to reason out my code and a basic logic tree was the only thing I was coming up with... I knew there was something better, just didn't explore it yet. Your info should give me a leg up for next week. I am now trying to figure out why I am seeing that 'nullptr' was not declared in this scope, but that seems more like I am missing a tidbit than going at it the wrong way.
ne555, good stuff to remember... I wasn't really sure how to state it, but I knew the issue was coming from that block. It looks far too ugly to be good code.
NT3, I am using a C++ 11 compiler so I suspect it is a issue with turning on support for nullptr as you say. However I do not seem to be having much luck finding where nullptr lives to turn it on.
Alright then... silly me. My problem with nullptr seems to have been that I did not need it as there is nothing to pass in when creating combatant1 (unless I am completely misunderstanding what is happening there (which is entirely possible)).
That unfortunately leaves me at
assignment3.cpp:245: error: request for member ‘reset’ in ‘combatant1’,
which is of non-class type ‘std::shared_ptr<combatant>()’
Oh sorry, I have two bits of code, with the same error and the only difference is the 'combatant1' and 'combatant2' as I am trying to do the same thing on two different objects. It seems to me like doubling the code and errors in a post is redundant and less than useful.
To get the version of the compiler, use g++ -v and it should give you some information. The most recent stable version is 4.8.2 (maybe 4.9 by now). Try just compiling, for example, the code in the link I posted to see if it is to do with the compiler or due to something else in your code that we might have missed.
flip3 ~/public_html/assignment3 157% g++ -std=c++0x test.cpp -o test.cpp
test.cpp:11: error: expected ‘;’ before ‘override’
test.cpp:12: error: expected ‘;’ before ‘}’ token
test.cpp:16: error: expected ‘;’ before ‘override’
test.cpp:17: error: expected ‘;’ before ‘}’ token
test.cpp: In function ‘int main()’:
test.cpp:23: error: ‘nullptr’ was not declared in this scope
So with that info it looks like a version issue with g++. Unfortunately, this is not something I have control over.
Well, it appears that that version of G++ is too old to have complete compatibility (it was released barely a year after C++11 became official, and the only changes were a few bug fixes). On a side note, why are you compiling it on top of itself?
Regardless, here is the same thing, without using C++11 options:
1 2 3 4 5 6 7 8 9
combatant* combatant1 = 0; // 0 instead of nullptr, raw pointers
if (menu == 1)
combatant1 = new warrior;
if (menu == 2)
combatant1 = new ranger;
// when ending, resetting or changing, remember to do this:
delete combatant1;
combatant1 = 0;
EDIT:
Actually, I just remembered - there is another option, which is to use the Boost libraries ( www.boost.org ). They provide std::shared_ptr and std::unique_ptr, as well as most of the other C++11 libraries (considering they came from Boost originally) in a cross compiler way. I'm pretty sure it supports down to G++3.4.
Oh I was compiling on itself because oops.... Just going to fast there.
Man, how do you keep versions straight?
Anyway, the version there compiles well until it hits my combat function where I pass the objects as a reference... it always has to be something doesn't it? void combat (combatant &comb1, combatant &comb2) { stuff;}
assignment3.cpp: In function ‘int main()’:
assignment3.cpp:255: error: invalid initialization of reference of type ‘combatant&’ from expression of type ‘combatant*’
assignment3.cpp:156: error: in passing argument 1 of ‘void combat(combatant&, combatant&)’
make: *** [assignment3] Error 1
I am wondering if I'll need a different way to pass these when using the above method.
In that case, you will need to either change the functions so that it takes a pointer instead of a reference, or dereference the pointer every time you send it to one of your functions. You can't do a reference straight off though (without some little hacks), because you cannot change what a reference points to. It is possible, though, so if you really want it as a reference that is fine.