polymorphism type error, I think...

D

deancoo

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
 
A

Allan Bruce

deancoo said:
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
 
P

Peter MacMillan

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: (e-mail address removed)
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(--)
 
A

Allan Bruce

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
 
D

Donovan Rebbechi

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,
 
D

deancoo

deancoo said:
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
 
O

Old Wolf

Allan said:
deancoo said:
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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,219
Latest member
KristieKoh

Latest Threads

Top