Board index » cppbuilder » oop basic question

oop basic question


2006-05-24 02:40:26 AM
cppbuilder53
I'm trying to get to grips with some basic oop, but there's something I'm
struggling with at the moment. The few lines of source are below.
I have class1 which inherits from TObject.
I have class2 which inherits from class1.
If I create an object of class2, I can access class1 methods through it, no
problem, which is fine.
But how do I call from class1 back into class2 (see below)? I've done
something similar in vb dotnet, and the MustOverride keyword makes it work.
How do I do it in C++ Builder?
Thanks
///////////////////////////
Main program:
class1 *a;
class2 *b;
a=new class1;
b=new class2;
a->F2(2); //calls directly into class1
b->F1(2); //calls through class2 into class1
delete a;
delete b;
//////////////////////////////
class declarations:
class class1 :TObject{
public:
int F1(int D1);
int F2(int D1);
virtual int F4(int D1);
};
class class2 : public class1
{
public:
int F3(int D1);
int F4(int D1);
};
/////////////////////////////
class code:
************************
int class1::F1(int D1)
{
}
int class1::F2(int D1)
{
F4(2); //how can I get this to call back into class 2? This executes
the F4() in class 1, below
}
int class1::F4(int D1)
{
}
**************************
int class2::F3(int D1)
{
F2(2);
}
int class2::F4(int D1)
{
}
 
 

Re:oop basic question

"IB" <none@none>writes:
Quote
class class1 :TObject{
public:

int F1(int D1);
int F2(int D1);
virtual int F4(int D1);
};

class class2 : public class1
{
public:
int F3(int D1);
int F4(int D1);


};


int class1::F1(int D1)
{
}

int class1::F2(int D1)
{
F4(2); //how can I get this to call back into class 2? This executes
the F4() in class 1, below
If this points to a class2 object, this call *will* invoke class2::F4.
 

Re:oop basic question

"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
"IB" <none@none>writes:

>class class1 :TObject{
>public:
>
>int F1(int D1);
>int F2(int D1);
>virtual int F4(int D1);
>};
>
>class class2 : public class1
>{
>public:
>int F3(int D1);
>int F4(int D1);
>
>
>};
>
>
>int class1::F1(int D1)
>{
>}
>
>int class1::F2(int D1)
>{
>F4(2); //how can I get this to call back into class 2? This executes
>the F4() in class 1, below

If this points to a class2 object, this call *will* invoke class2::F4.
... but I don't want it to explicitly point to class2, as I want my class1
to be able to inheritable by any class, and be able to call (in a general
purpose way) into the class which inherited it.
 

{smallsort}

Re:oop basic question

"IB" <none@none>writes:
Quote
... but I don't want it to explicitly point to class2, as I want my
class1 to be able to inheritable by any class, and be able to call
(in a general purpose way) into the class which inherited it.
I don't write about "explicitly".
If you define a variable of class2, as in
class2 myObject2;
and invoke F2() on it, as in
myObject2.F2();
, the call to F4() in the body of class1::F2() will cause class2::F4()
to be invoked, because F4() is declared virtual in the definition of
class1 and because that F4() is overriden by class2.
 

Re:oop basic question

"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
If you define a variable of class2, as in

class2 myObject2;

and invoke F2() on it, as in

myObject2.F2();

, the call to F4() in the body of class1::F2() will cause class2::F4()
to be invoked, because F4() is declared virtual in the definition of
class1 and because that F4() is overriden by class2.
But it sounds like he wants to create a class1 object and
have it somehow invoke the function from class2. He also says
that he wants class1 to be able to call into whatever class
inherits it so maybe I'm not understanding the question.
 

Re:oop basic question

"IB" <none@none>wrote in message
Quote
I'm trying to get to grips with some basic oop, but there's
something I'm struggling with at the moment. The few lines of source
are below.

I have class1 which inherits from TObject.
I have class2 which inherits from class1.

If I create an object of class2, I can access class1 methods through
it, no problem, which is fine.

But how do I call from class1 back into class2 (see below)? I've
done something similar in vb dotnet, and the MustOverride keyword
makes it work. How do I do it in C++ Builder?

Thanks


///////////////////////////
Main program:

class1 *a;
class2 *b;

a=new class1;
b=new class2;
a->F2(2); //calls directly into class1
b->F1(2); //calls through class2 into class1

Your example calls a->F2(2). Did you also want to call b->F2(2) ?
--
Bruce
 

Re:oop basic question

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote

"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>If you define a variable of class2, as in
>
>class2 myObject2;
>
>and invoke F2() on it, as in
>
>myObject2.F2();
>
>, the call to F4() in the body of class1::F2() will cause class2::F4()
>to be invoked, because F4() is declared virtual in the definition of
>class1 and because that F4() is overriden by class2.

But it sounds like he wants to create a class1 object and
have it somehow invoke the function from class2. He also says
that he wants class1 to be able to call into whatever class
inherits it so maybe I'm not understanding the question.

Sorry if I'm not asking the question clearly, but in my example, class2
inherits class1. In my application, I also have a class3 which inherits a
class1, and a class4 which inherits class1, etc.
class1 is a filereader, and the other classes which inherit it deal with
different file formats. So what I am trying to do is to put the basic file
reading and data stripping in class1, it then calls back into the higher
level classes with the basic chunks of data I (in a general purpose way),
and the higher level classes deal with the formatting.
So class1 gets X,Y,and operation data (from a file), class2 uses class1 and
processes the data into gerber information, class3 uses class1 and processes
it into hpgl, etc.
My basic class1 has to call back into any class which inherits it, with
x,y,and operation, data, as it scans the user file.
 

Re:oop basic question

"IB" <none@none>wrote in message news: XXXX@XXXXX.COM ...
Quote
But how do I call from class1 back into class2 (see below)?
It does it automatically. Your F4() method is virtual in class1, and class2
is overidding it. When class1::F2() calls F4(), it automatically calls into
class2 ::F4() instead of class1::F4(). The only situation where that would
not be the case is when F4() is called in class1's constructor or
destructor, since class2 does not exist in class1's vtable at those two
times.
Quote
I've done something similar in vb dotnet, and the MustOverride
keyword makes it work.
VB.NET's MustOverride keyword is equivilent to C++ declaring a pure virtual
method.
Gambit
 

Re:oop basic question

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote
it sounds like he wants to create a class1 object and
have it somehow invoke the function from class2.
That is not possible. The 'this' pointer that is passed to class1::F2()
does not point to a class2 instance, so there is no way for class2::F4() to
be called by class1::F2(). F2() must be called upon an instance of class2
(or a descendant of class2) in order for class1::F2() to call class2::F4().
Gambit
 

Re:oop basic question

"IB" <none@none>wrote in message news: XXXX@XXXXX.COM ...
Quote
class1 is a filereader, and the other classes which inherit it deal
with different file formats. So what I am trying to do is to put the
basic file reading and data stripping in class1, it then calls back into
the higher level classes with the basic chunks of data I (in a general
purpose way), and the higher level classes deal with the formatting.
The code you showed earlier will already handle that just fine AS LONG AS
you are calling the methods on instances of the derived classes and not on
instances of the base class itself. In other words:
class1 a;
class2 b;
a.F2(2); // <-- is not a class2 instance, cannot call class2::F4()
b.F2(2); // <-- is a class2 instance, will call class2::F4()
Also:
class1 *a;
class1 *b; // <-- not a typo! using a class1 pointer to hold a derived
class
a = new class1;
b = new class2;
a->F2(2); // <-- is not a class2 instance, cannot call class2::F4()
b->F2(2); // <-- is a class2 instance, will call class2::F4()
Gambit
 

Re:oop basic question

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
news:4473747d$ XXXX@XXXXX.COM ...

>it sounds like he wants to create a class1 object and
>have it somehow invoke the function from class2.

That is not possible. The 'this' pointer that is passed to class1::F2()
does not point to a class2 instance, so there is no way for class2::F4()
to
be called by class1::F2(). F2() must be called upon an instance of class2
(or a descendant of class2) in order for class1::F2() to call
class2::F4().
I know it's not possible. But this sounds like what he's
asking. Maybe it's a communication thing. I'm not sure
what he means by getting the base class function to "call
back" into the derived class:
Quote
int class1::F2(int D1)
{
F4(2); //how can I get this to call back into class 2? This executes
the F4() in class 1, below
}
In this example, class1 is the base class. How can it know
about F4() which is a function in a derived class?
 

Re:oop basic question

"IB" <none@none>wrote in message news: XXXX@XXXXX.COM ...
Quote

My basic class1 has to call back into any class which inherits it, with
x,y,and operation, data, as it scans the user file.
It's the call back that I don't understand. You also seem
to be implying that the base class can somehow know
who is derived from it.
If class2 is derived from class1 and the F4() function is
public or protected in the base, then the derived class has
it as well. When you derive it like this, class2 ISA class1.
By making the same function in class2, you're forcing it
to use the one in class2.
Maybe what you want is to remove the function from
the derived classes and just use the one inherited from
the base.
class class1 :TObject{
public:
int F1(int D1);
int F2(int D1);
int F4(int D1);
};
class class2 : public class1
{
public:
int F3(int D1);
//int F4(int D1);
};
class1 a;
class2 b;
a.F4(42); // both can access F4()
b.F4(42);
You would use a virtual function as you show
if you wanted it to do something different in the derived
class. Making it virtual assures that the most derived one
is called so when you do something like
(with you're original code)
class1* spoo = new class2; // polymorphically via base class *
spoo->F4(42); // this calls the function from class2.
class1* doh = new class1;
doh->F4(42); // this calls the function from class 1
You can also access the base class's function using
class1::F4(). So in class2's function F4() you can
do something like:
int class2::F4(int x) {
// do stuff specific to class2
class1::F4(x);
}
Sorry if I'm still not understanding your problem.
 

Re:oop basic question

"IB" <none@none>wrote:
(nitpicking because the main question has been answered)
Quote
class class1 :TObject{
Any reason to be using TObject as a base class? Its major effect here
seems to be that you're having to declare your objects on the heap,
rather than using them on the stack:
Quote
class1 *a;
class2 *b;

a=new class1;
b=new class2;
a->F2(2); //calls directly into class1
b->F1(2); //calls through class2 into class1


delete a;
delete b;
class1 a;
class2 b;
a.F2(2); //calls directly into class1
b.F1(2); //calls through class2 into class1
// delete not wanted any more.
Alan Bellingham
--
Team Thai Kingdom
<url:www.borland.com/newsgroups/>Borland newsgroup descriptions
<url:www.borland.com/newsgroups/netiquette.html>netiquette
 

Re:oop basic question

"IB" <none@none>wrote:
Quote
class1 *a;
class2 *b;

a=new class1;
b=new class2;
a->F2(2); //calls directly into class1
b->F1(2); //calls through class2 into class1
What you are looking for is how to make a method pure virtual. This is done by assigning zero in the declaration:
class class1 : TObject
{
public:
int F1(int D1);
int F2(int D1);
virtual int F4(int D1) = 0;
};
Doing so you cannot create a class1 instance directly anymore,
but must inherit from it:
class1 *a;
a = new class1; // gives a compilation error
a = new class2; // is okay
You see, you would use class1 pointers to treat your instances
all the same although they are of different derivates. Depending
on what you are doing with your instances, you would either use
an array of class1 pointers to access the objects
std::vector<class1*>vecMyObjects;
vecMyObjects.push_back(new class2);
etc.
vecMyObjects[0]->F4(2);
or use class specific pointers, but functions using class1
pointer arguments:
class2* pMyObject = new class2;
MyFunction(pMyObject);
void MyFunction(class1* apMyObject)
{
apMyObject->F4(2);
}
The code you posted where F4 is called within F2 is absolutely
okay. There should be no problem with it. Maybe you were
mistaken and created a class1 instance. This would of course
not call F4 of class2, because it is not F2. Well with F4 being
pure virtual, you cannot make this mistake anymore.
At last, I know you just created a sample from scratch, so I
guess you know about naming conventions. If not:
class class1 : TObject
{
public:
int F1(int D1);
int F2(int D1);
virtual int F4(int D1) = 0;
};
should read like
class TClass1 : TObject
{
public:
int f1(int d1);
int f2(int d1);
virtual int f4(int d1) = 0;
};
 

Re:oop basic question

Quote
What you are looking for is how to make a method pure virtual. This is
done by assigning zero in the declaration:

class class1 : TObject
{
public:
int F1(int D1);
int F2(int D1);
virtual int F4(int D1) = 0;
};

Doing so you cannot create a class1 instance directly anymore,
but must inherit from it:

Many thanks to all for the fantastic response, this looks like the closest
answer to the question I thought I was asking, I'll try it out and let you
know.