By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,918 Members | 2,279 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,918 IT Pros & Developers. It's quick & easy.

polymorphism type error, I think...

P: n/a
Hello all, I'm having a problem compiling some code which I believe should
compile. Can someone tell me what I'm doing wrong. The code in question
is appended below, followed by the compiler output.

Thanks,
d

PS: uncommenting the commented out code allows the program to compile.

------------------------------------------------
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class dummy_obj {
public:
int test_int;
string test_string;
void say_it() {
cout << test_string << endl;
};
};

class dummy_obj_a : public dummy_obj {
public:
dummy_obj_a() {
test_int = 0;
test_string = "Hello Joe";
};
};

class dummy_obj_b : public dummy_obj {
public:
dummy_obj_b() {
test_int = 0;
test_string = "Goodbye Joe";
};
};

int main(int argc, char *argv[])
{
vector<dummy_obj*> my_objs;

char x = 'a';
// dummy_obj_a *obj = new dummy_obj_a;

if (x == 'a') {
dummy_obj_a *obj = new dummy_obj_a;
} else if (x == 'b') {
dummy_obj_b *obj = new dummy_obj_b;
};

my_objs.push_back(obj);

for (vector<dummy_obj*>::iterator z=my_objs.begin(); z!=my_objs.end();
z++) {
(*z)->say_it();
};

system("PAUSE");
return EXIT_SUCCESS;
}

-----------------------------------------------------------

Compiler: Default compiler
Building Makefile: "M:\A\cpp_dev\test\Makefile.win"
Executing make...
make.exe -f "M:\A\cpp_dev\test\Makefile.win" all
g++.exe -c ptr_object_definition_test.cpp -o
ptr_object_definition_test.o -I"M:/A/cpp_dev/poker/include" -I"lib/gcc/mingw32/3.4.2/include"
-I"include/c++/3.4.2/backward" -I"include/c++/3.4.2/mingw32" -I"include/c++/3.4.2"
-I"include" -g3 -O0

ptr_object_definition_test.cpp: In function `int main(int, char**)':
ptr_object_definition_test.cpp:48: error: `obj' undeclared (first use this
function)
ptr_object_definition_test.cpp:48: error: (Each undeclared identifier is
reported only once for each function it appears in.)

make.exe: *** [ptr_object_definition_test.o] Error 1

Execution terminated

Jul 23 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"deancoo" <s2*******@yahoo.ca> wrote in message
news:kcC1e.11597$x8.2067@edtnps90...
Hello all, I'm having a problem compiling some code which I believe should
compile. Can someone tell me what I'm doing wrong. The code in question
is appended below, followed by the compiler output.

Thanks,
d

PS: uncommenting the commented out code allows the program to compile.

------------------------------------------------
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class dummy_obj {
public:
int test_int;
string test_string;
void say_it() {
cout << test_string << endl;
};
};

class dummy_obj_a : public dummy_obj {
public:
dummy_obj_a() {
test_int = 0;
test_string = "Hello Joe";
};
};

class dummy_obj_b : public dummy_obj {
public:
dummy_obj_b() {
test_int = 0;
test_string = "Goodbye Joe";
};
};

int main(int argc, char *argv[])
{
vector<dummy_obj*> my_objs;

char x = 'a';
// dummy_obj_a *obj = new dummy_obj_a;

if (x == 'a') {
dummy_obj_a *obj = new dummy_obj_a;


here you have created a variable called obj but only has scope within this
block (between the { and } )
therefore when you use obj below to push_back there is no such variable,
hence the error.

If you have the line uncommented then your obj has the correct scope, but
you have a memory leak as you create two new instances of the object for one
variable, perhaps you mean something like this:

// variable to store your dummy object, not this is the base class here
dummy_obj *obj;

if (x == 'a') {
// create a dummy_object_a which can be stored in obj
obj = new dummy_obj_a(); // remember the () to call the constructor!
} else if (x == 'b') {
obj = new dummy_obj_b;
};

HTH
Allan
Jul 23 '05 #2

P: n/a
"deancoo" <s2*******@yahoo.ca> wrote in
news:kcC1e.11597$x8.2067@edtnps90:
Hello all, I'm having a problem compiling some code which I believe
should compile. Can someone tell me what I'm doing wrong. The code
in question is appended below, followed by the compiler output.

Thanks,
d

PS: uncommenting the commented out code allows the program to
compile.

Your problem has nothing to do with polymorphism and everything to do with
scope.
// dummy_obj_a *obj = new dummy_obj_a;

if (x == 'a') {
dummy_obj_a *obj = new dummy_obj_a;
} else if (x == 'b') {
dummy_obj_b *obj = new dummy_obj_b;
};

my_objs.push_back(obj);


obj is being defined out of scope. That is, when the if block is done, the
variable is lost.

replace with:

dummy_obj *obj;

if (x == 'a') {
obj = new dummy_obj_a;
} else if (x == 'b') {
obj = new dummy_obj_b;
} else {
obj = NULL;
};

my_objs.push_back(obj);
The else block will prevent a compiler warning against uninitialized code.
Think about the worst case when both if statements fail - there is no value
assigned to the obj variable.

Also, notice how I changed the initialization to the base type? You can
cast to parent classes but not to siblings.

type: dummy_obj* accepts: dummy_obj* and pointers to inheriting objects
type: dummy_obj_a* accepts: dummy_obj_a* and pointers to...

since dummy_obj_b does not inherit from dummy_obj_b, you cannot cast it to
dummy_obj_a (and vice versa) - it doesn't make sense.

Cheers.


--
Peter MacMillan
e-mail/msn: pe***@writeopen.com
icq: 1-874-927

GCS/IT/L d-(-)>-pu s():(-) a- C+++(++++)>$ UL>$ P++ L+ E-(-) W++(+++)>$ N o
w++>$ O !M- V PS PE Y+ t++ 5 X R* tv- b++(+) DI D+(++)>$ G e++ h r-- y(--)
Jul 23 '05 #3

P: n/a
> here you have created a variable called obj but only has scope within this
block (between the { and } )
therefore when you use obj below to push_back there is no such variable,
hence the error.

If you have the line uncommented then your obj has the correct scope, but
you have a memory leak as you create two new instances of the object for
one variable, perhaps you mean something like this:

// variable to store your dummy object, not this is the base class here
dummy_obj *obj;

if (x == 'a') {
// create a dummy_object_a which can be stored in obj
obj = new dummy_obj_a(); // remember the () to call the
constructor!
} else if (x == 'b') {
obj = new dummy_obj_b;


forgot the brackets here too, the line above should be:
obj = new dummy_obj_b();

Allan
Jul 23 '05 #4

P: n/a
On 2005-03-27, Allan Bruce <no****@btinternet.com> wrote:

obj = new dummy_obj_a(); // remember the () to call the constructor!


parens are unnecessary here. new X is the same as new X(). Both
default-initialize the object (which means "call the default constructor" in
this case). The standard does not distinguish between new X and new X() --
both are covered by the same rule (12.6#1)

Cheers,
--
Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/
Jul 23 '05 #5

P: n/a

"deancoo" <s2*******@yahoo.ca> wrote in message
news:kcC1e.11597$x8.2067@edtnps90...
Hello all, I'm having a problem compiling some code which I believe should
compile. Can someone tell me what I'm doing wrong. The code in question
is appended below, followed by the compiler output.

Thanks,
d

PS: uncommenting the commented out code allows the program to compile.

------------------------------------------------
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class dummy_obj {
public:
int test_int;
string test_string;
void say_it() {
cout << test_string << endl;
};
};

class dummy_obj_a : public dummy_obj {
public:
dummy_obj_a() {
test_int = 0;
test_string = "Hello Joe";
};
};

class dummy_obj_b : public dummy_obj {
public:
dummy_obj_b() {
test_int = 0;
test_string = "Goodbye Joe";
};
};

int main(int argc, char *argv[])
{
vector<dummy_obj*> my_objs;

char x = 'a';
// dummy_obj_a *obj = new dummy_obj_a;

if (x == 'a') {
dummy_obj_a *obj = new dummy_obj_a;
} else if (x == 'b') {
dummy_obj_b *obj = new dummy_obj_b;
};

my_objs.push_back(obj);

for (vector<dummy_obj*>::iterator z=my_objs.begin(); z!=my_objs.end();
z++) {
(*z)->say_it();
};

system("PAUSE");
return EXIT_SUCCESS;
}

-----------------------------------------------------------

Compiler: Default compiler
Building Makefile: "M:\A\cpp_dev\test\Makefile.win"
Executing make...
make.exe -f "M:\A\cpp_dev\test\Makefile.win" all
g++.exe -c ptr_object_definition_test.cpp -o
ptr_object_definition_test.o -I"M:/A/cpp_dev/poker/include" -I"lib/gcc/mingw32/3.4.2/include"
-I"include/c++/3.4.2/backward" -I"include/c++/3.4.2/mingw32" -I"include/c++/3.4.2"
-I"include" -g3 -O0

ptr_object_definition_test.cpp: In function `int main(int, char**)':
ptr_object_definition_test.cpp:48: error: `obj' undeclared (first use this
function)
ptr_object_definition_test.cpp:48: error: (Each undeclared identifier is
reported only once for each function it appears in.)

make.exe: *** [ptr_object_definition_test.o] Error 1

Execution terminated


Thanks guys. Once I got it through my head that the problem was scope,
which I kind of subconsciously suspected, it all comes together.

Thanks again,
d
Jul 23 '05 #6

P: n/a
Allan Bruce wrote:
"deancoo" <s2*******@yahoo.ca> wrote:

class dummy_obj {
public:
int test_int;
string test_string;
void say_it() {
cout << test_string << endl;
};
};

class dummy_obj_a : public dummy_obj {
public:
dummy_obj_a() {
test_int = 0;
test_string = "Hello Joe";
};
};

class dummy_obj_b : public dummy_obj {
public:
dummy_obj_b() {
test_int = 0;
test_string = "Goodbye Joe";
};
};

int main(int argc, char *argv[])
{
vector<dummy_obj*> my_objs;
dummy_obj *obj;

if (x == 'a') {
obj = new dummy_obj_a();
// remember the () to call the constructor!


There is no need for the brackets.

I believe that C++03 mandates that 'new X' default-initializes
the object and 'new X()' value-initializes the object, the
difference being that value-initialization means that ints are
set to 0, etc.
} else if (x == 'b') {
obj = new dummy_obj_b;
};


Unnecessary semicolon.
my_objs.push_back(obj);
for (vector<dummy_obj*>::iterator z=my_objs.begin();
z!=my_objs.end(); z++) {
(*z)->say_it();
};

return EXIT_SUCCESS;
}


There's another serious problem here: it isn't possible to
delete the objects that have been created.

Deleting the pointers in the vector would be undefined
behaviour, because the base class doesn't have a virtual
destructor.

Jul 23 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.