problems with abstract classes

  • Thread starter Christian Christmann
  • Start date
C

Christian Christmann

Hi,

I've a class Handler which contains a STL list
std::list<Abstract*> mAbstract;
which is storing elements of the abstract class Abstract.
Further this class has a getElement function to
return a specific element of the list.

The abstract class Abstract has some virtual pure function
which are used with all concrete classes derived from it.

One of the concrete classes derived from Abstract, let's
call it Concrete_A, has some public functions of specific purpose
and therefore not defined in the abstract class but just in
Concrete_A. Let's assume that one function is
double getTime();

In the future there should be some more concrete classes which
are used for other purposes. To have a "generic model" they
should be derived from class Abstract and added to the STL list
of the handler and finally be accessed by the Handler.

Now let's assume that I have another class Class_A which has a pointer
to the Handler class. Now, my idea is to retrieve the element from the
STL list using the handler and that call the function getTime:

Class_A *object = new Class_A;
double t = object->getHandler()->getElement(_ID_)->getTime();
// _ID_ is a specification of the element from list mAbstract

Doing that the compiler issues an error telling me that the function
getTime() is not known in class Objective.

I though it would be possible to use pointers to objects of the class
Abstract in the STL list of the class Handler and thus the compiler would
recognize at run-time that it's an object of class Concrete_A and call the
corresponding function getTime().
Is this approach feasible? If so, what am I doing wrong?


Thank you.

Chris
 
V

vindhya

Could following be done.....
(Here Class_test is the concrete derived from abstract)

Class_test *ct1 = new Class_test;
ct1 = object->getHandler()->getEleme­nt(_ID_);
double_t = ct1->getTime();
 
V

vindhya

Could you provide the pseudo code.
You say that ur list contains of abstract class. And you have this
gettime function defined in derived class.
Now u r creating a handle to elements in abstract class list. When you
try to access it then you are using a base class pointer to a base
class member.
For virtual function to come into picture I presume your gettime will
be virtual in base class and handler will use base class pointer of
derived class object type, which I dont find in your statements above.
What do ya say. I think it will be more clear with pseudo code.
 
H

Heinz Ozwirk

Christian Christmann said:
Hi,

I've a class Handler which contains a STL list
std::list<Abstract*> mAbstract;
which is storing elements of the abstract class Abstract.
Further this class has a getElement function to
return a specific element of the list.

The abstract class Abstract has some virtual pure function
which are used with all concrete classes derived from it.

One of the concrete classes derived from Abstract, let's
call it Concrete_A, has some public functions of specific purpose
and therefore not defined in the abstract class but just in
Concrete_A. Let's assume that one function is
double getTime();

In the future there should be some more concrete classes which
are used for other purposes. To have a "generic model" they
should be derived from class Abstract and added to the STL list
of the handler and finally be accessed by the Handler.

Now let's assume that I have another class Class_A which has a pointer
to the Handler class. Now, my idea is to retrieve the element from the
STL list using the handler and that call the function getTime:

Class_A *object = new Class_A;
double t = object->getHandler()->getElement(_ID_)->getTime();
// _ID_ is a specification of the element from list mAbstract

Doing that the compiler issues an error telling me that the function
getTime() is not known in class Objective.

I though it would be possible to use pointers to objects of the class
Abstract in the STL list of the class Handler and thus the compiler would
recognize at run-time that it's an object of class Concrete_A and call the
corresponding function getTime().

How can the compiler recognize anything at run-time? The program might even
be running on a machine where no compiler has ever been installed. And what
were the compiler supposed to do if the object does not support the required
method?

Before you can call a member function of a derived class, that is not also a
(virtual) member of the base class, you have to test whether the pointer you
get from you list actually points to an instance of a derived class, that
supports that function. You have to break your statement into several parts:

Concret_A* derived =
dynamic_cast<Concret_A*>(object->getHandler->getElement(_ID_));
if (derived != 0)
{
t = derived->getTime();
}

dynamic_cast tests (at run-time) whether the object pointed to actually is
of the required type. If it is, it returns a pointer to that type, otherwise
it returns 0. Only if the pointer is non-zero you can access methods of the
now known type.

HTH
Heinz
 
U

ulrich

Hi,

I've a class Handler which contains a STL list
std::list<Abstract*> mAbstract;
which is storing elements of the abstract class Abstract.
Further this class has a getElement function to
return a specific element of the list.

The abstract class Abstract has some virtual pure function
which are used with all concrete classes derived from it.

One of the concrete classes derived from Abstract, let's
call it Concrete_A, has some public functions of specific purpose
and therefore not defined in the abstract class but just in
Concrete_A. Let's assume that one function is
double getTime();

In the future there should be some more concrete classes which
are used for other purposes. To have a "generic model" they
should be derived from class Abstract and added to the STL list
of the handler and finally be accessed by the Handler.

Now let's assume that I have another class Class_A which has a pointer
to the Handler class. Now, my idea is to retrieve the element from the
STL list using the handler and that call the function getTime:

Class_A *object = new Class_A;
double t = object->getHandler()->getElement(_ID_)->getTime();
// _ID_ is a specification of the element from list mAbstract

Doing that the compiler issues an error telling me that the function
getTime() is not known in class Objective.

I though it would be possible to use pointers to objects of the class
[...] thus the compiler would
recognize at run-time [...]

that's a contradicton per se. at run-time, the compiler has long done its
job. the compiler will not recognize anything at run-time.
it does not work like you imagine: in order to call a method declared in
the concrete derived class, you must have a pointer of this type. so you
need to type cast the pointer to your abstract base class in order to
access a method of the derived class which the latter did not inherit from
the base class.
however, i could imagine that this contradicts the purpose of your list of
pointers to the base class. still, with a pointer to your base class, you
can only access methods (at least) declared in this base class.
 
V

vindhya

Probably this may answer ur query. I havent written handler.


#include <iostream>
#include <list>
using namespace std;

class abstract_class {
public:
virtual void printsomething() = 0;
virtual ~abstract_class(){};
};
class derived :public abstract_class {
public:
void printsomething() { cout << "In derived
printsomething" << endl; }
};
int main() {

std::list<abstract_class*> mylist;
abstract_class *x = new derived();
mylist.push_front(x);

list<abstract_class*>::iterator i;
for ( i=mylist.begin() ; i!=mylist.end() ; ++i) {
cout << *i << endl;
abstract_class* y = new derived();
y = *i;
y->printsomething();
}
}
 
V

vindhya

In fact you can cut short following lines

abstract_class* y = new derived();
y = *i;
y->printsomething();

to

abstract_class* y
y = *i;
y->printsomething();
 
C

Christian Christmann

Concret_A* derived =
dynamic_cast<Concret_A*>(object->getHandler->getElement(_ID_));
if (derived != 0)
{
t = derived->getTime();
}
}
dynamic_cast tests (at run-time) whether the object pointed to actually is
of the required type. If it is, it returns a pointer to that type,
otherwise it returns 0. Only if the pointer is non-zero you can access
methods of the now known type.

Thank you. This was exactly what I was looking for.
HTH
Heinz
Best regards,
Chris
 
C

Christian Christmann

that's a contradicton per se. at run-time, the compiler has long done its
job. the compiler will not recognize anything at run-time. it does not
work like you imagine: in order to call a method declared in the concrete
derived class, you must have a pointer of this type. so you need to type
cast the pointer to your abstract base class in order to access a method
of the derived class which the latter did not inherit from the base class.
however, i could imagine that this contradicts the purpose of your list of
pointers to the base class. still, with a pointer to your base class, you
can only access methods (at least) declared in this base class.


Thank you, dynamic casting was the solution. I used the approach
Heinz suggested in his post and it words fine.

Chris
 
C

Christian Christmann

Could you provide the pseudo code.
You say that ur list contains of abstract class. And you have this gettime
function defined in derived class. Now u r creating a handle to elements
in abstract class list. When you try to access it then you are using a
base class pointer to a base class member.
For virtual function to come into picture I presume your gettime will be
virtual in base class and handler will use base class pointer of derived
class object type, which I dont find in your statements above. What do ya
say. I think it will be more clear with pseudo code.

Thank you for your answer.
I think the easiest way to solve the problem
is to use dynamic casting as Heinz suggested in his post. I tried it here
and it works.

Chris
 

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

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top