executing a child method when pointed to by a base class pointer

P

Peter Oliphant

Is there a way of defining a method in a base class such that derived
classes will call their own version, EVEN if the derived instance is
referred to by a pointer to the base class? Note that the base class method
is not to be abstract, and will be called if the instance was created as a
'generic' base class instance.

It's sort of like I want the method to be abstract to children, but concrete
at the base level. That way I can refer to an array of pointers to base
class elements that each will call its child's version of the method when
asked to execute this method (without being told (i.e., cast to) it's of
'child class' type).

Is this possible? I could create an abstract class that has this method as
abstract and derive both 'base class' and 'child class' from it, in which
case a pointer to the abstract class that holds an instance of the base or
child class will execute the approriate method. But then the 'child class'
is no longer a child of the 'base class'. I'd rather do it like I described
above...

Thanks in avance for responses! : )

[==P==]
 
D

David Wilkinson

Peter said:
Is there a way of defining a method in a base class such that derived
classes will call their own version, EVEN if the derived instance is
referred to by a pointer to the base class? Note that the base class method
is not to be abstract, and will be called if the instance was created as a
'generic' base class instance.

It's sort of like I want the method to be abstract to children, but concrete
at the base level. That way I can refer to an array of pointers to base
class elements that each will call its child's version of the method when
asked to execute this method (without being told (i.e., cast to) it's of
'child class' type).

Is this possible? I could create an abstract class that has this method as
abstract and derive both 'base class' and 'child class' from it, in which
case a pointer to the abstract class that holds an instance of the base or
child class will execute the approriate method. But then the 'child class'
is no longer a child of the 'base class'. I'd rather do it like I described
above...

Thanks in avance for responses! : )

[==P==]
Peter:

Maybe I'm missing something, but why don't you just make the method
virtual and have an implementation in the base class. Or if you don't
like that, then make a new abstract class and do

abstract -> base -> derived

BTW, IMHO it is not good to use the term "child class". Use "derived
class" or "sub-class". Child often has another meaning, like
parent-child in Windows.

David Wilkinson
 
C

Carl Daniel [VC++ MVP]

Peter Oliphant said:
Is there a way of defining a method in a base class such that derived
classes will call their own version, EVEN if the derived instance is
referred to by a pointer to the base class? Note that the base class
method is not to be abstract, and will be called if the instance was
created as a 'generic' base class instance.

It's sort of like I want the method to be abstract to children, but
concrete at the base level. That way I can refer to an array of pointers
to base class elements that each will call its child's version of the
method when asked to execute this method (without being told (i.e., cast
to) it's of 'child class' type).

Is this possible? I could create an abstract class that has this method as
abstract and derive both 'base class' and 'child class' from it, in which
case a pointer to the abstract class that holds an instance of the base or
child class will execute the approriate method. But then the 'child class'
is no longer a child of the 'base class'. I'd rather do it like I
described above...

This is just basic polymorphism, as implemented by virtual functions in both
native C++ and .NET.

Simply declare the function virtual in the base class and override it in the
derived class(es). Calls through a pointer (or reference) to the base class
will in fact call the implementation supplied by the derived class.

If you don't want an implementation in the base class, declare it "pure"
(=0) in native C++, or abstract in .NET, otherwise you'll have to supply a
definition of the function in the base class as well.

-cd
 
P

Peter Oliphant

Maybe I'M missing something, but this is what I'm experiencing:

ref class baseClass
{
public:
baseClass() {}
~baseClass() {}

protected:
virtual void func() {}
} ;

ref childClass : public baseClass
{
public:
childClass() {}
~childClass() {}

protected:
virtual void func() override {}
} ;

int main()
{
childClass^ child = gcnew childClass() ;

baseClass^ base_child_ptr = child ;

base_child_ptr->func() ; // execute base version!
}

At least I think this is what I'm experiencing, typo I haven't noticed not
withstanding... : )

[==P==]
 
C

Carl Daniel [VC++ MVP]

Peter Oliphant said:
Maybe I'M missing something, but this is what I'm experiencing:
[ code snipped ]
At least I think this is what I'm experiencing, typo I haven't noticed not
withstanding... : )

No, that definitely will execute the derived class version. Add some
Console.WriteLine's (or Trace or whatever) to the two functions to see for
sure.

using namespace System;

ref class baseClass
{
public:
baseClass() {}
~baseClass() {}

public:
virtual void func() { Console::WriteLine("Base version"); }
} ;

ref class childClass : public baseClass
{
public:
childClass() {}
~childClass() {}

public:
virtual void func() override { Console::WriteLine("Derived version"); }
} ;

int main()
{
childClass^ child = gcnew childClass() ;

baseClass^ base_child_ptr = child ;

base_child_ptr->func() ; // execute base version!
}

-cd
 
N

Nishant Sivakumar

Show your actual code - the code you posted won't even compile. And if it
was fixed to get it to compile fine - by adding the class keyword before
childClass and changing the protected access to public (for func), the
derived class method gets invoked.

--
Regards,
Nish [VC++ MVP]


Peter Oliphant said:
Maybe I'M missing something, but this is what I'm experiencing:

ref class baseClass
{
public:
baseClass() {}
~baseClass() {}

protected:
virtual void func() {}
} ;

ref childClass : public baseClass
{
public:
childClass() {}
~childClass() {}

protected:
virtual void func() override {}
} ;

int main()
{
childClass^ child = gcnew childClass() ;

baseClass^ base_child_ptr = child ;

base_child_ptr->func() ; // execute base version!
}

At least I think this is what I'm experiencing, typo I haven't noticed not
withstanding... : )

[==P==]

Carl Daniel said:
This is just basic polymorphism, as implemented by virtual functions in
both native C++ and .NET.

Simply declare the function virtual in the base class and override it in
the derived class(es). Calls through a pointer (or reference) to the
base class will in fact call the implementation supplied by the derived
class.

If you don't want an implementation in the base class, declare it "pure"
(=0) in native C++, or abstract in .NET, otherwise you'll have to supply
a definition of the function in the base class as well.

-cd
 
P

Peter Oliphant

The only reason it won't compile is I forgot the word 'class' in forn of the
'childClass' definition.

And, it turns out this code does behave correctly (i.e., execute
'childClass' version). I must be doing something else in my 'real' code. I
can't post all my code, you wouldn't like that, it's like 30,000 line long,
this was a reduced version... : )

[==P==]

Nishant Sivakumar said:
Show your actual code - the code you posted won't even compile. And if it
was fixed to get it to compile fine - by adding the class keyword before
childClass and changing the protected access to public (for func), the
derived class method gets invoked.

--
Regards,
Nish [VC++ MVP]


Peter Oliphant said:
Maybe I'M missing something, but this is what I'm experiencing:

ref class baseClass
{
public:
baseClass() {}
~baseClass() {}

protected:
virtual void func() {}
} ;

ref childClass : public baseClass
{
public:
childClass() {}
~childClass() {}

protected:
virtual void func() override {}
} ;

int main()
{
childClass^ child = gcnew childClass() ;

baseClass^ base_child_ptr = child ;

base_child_ptr->func() ; // execute base version!
}

At least I think this is what I'm experiencing, typo I haven't noticed
not withstanding... : )

[==P==]

"Carl Daniel [VC++ MVP]"
Is there a way of defining a method in a base class such that derived
classes will call their own version, EVEN if the derived instance is
referred to by a pointer to the base class? Note that the base class
method is not to be abstract, and will be called if the instance was
created as a 'generic' base class instance.

It's sort of like I want the method to be abstract to children, but
concrete at the base level. That way I can refer to an array of
pointers to base class elements that each will call its child's version
of the method when asked to execute this method (without being told
(i.e., cast to) it's of 'child class' type).

Is this possible? I could create an abstract class that has this method
as abstract and derive both 'base class' and 'child class' from it, in
which case a pointer to the abstract class that holds an instance of
the base or child class will execute the approriate method. But then
the 'child class' is no longer a child of the 'base class'. I'd rather
do it like I described above...

This is just basic polymorphism, as implemented by virtual functions in
both native C++ and .NET.

Simply declare the function virtual in the base class and override it in
the derived class(es). Calls through a pointer (or reference) to the
base class will in fact call the implementation supplied by the derived
class.

If you don't want an implementation in the base class, declare it "pure"
(=0) in native C++, or abstract in .NET, otherwise you'll have to supply
a definition of the function in the base class as well.

-cd
 
P

Peter Oliphant

Yrah, I tested my code example (which I had never tested, just thought I was
boiling down what I actually do, apparently its not 'exactly' what I do) and
it does execute 'childClass' version. I must be doing something different in
my 'real code'... : )

Sorry for the brain-dead post... LOL

[==P==]

Carl Daniel said:
Peter Oliphant said:
Maybe I'M missing something, but this is what I'm experiencing:
[ code snipped ]
At least I think this is what I'm experiencing, typo I haven't noticed
not withstanding... : )

No, that definitely will execute the derived class version. Add some
Console.WriteLine's (or Trace or whatever) to the two functions to see for
sure.

using namespace System;

ref class baseClass
{
public:
baseClass() {}
~baseClass() {}

public:
virtual void func() { Console::WriteLine("Base version"); }
} ;

ref class childClass : public baseClass
{
public:
childClass() {}
~childClass() {}

public:
virtual void func() override { Console::WriteLine("Derived version"); }
} ;

int main()
{
childClass^ child = gcnew childClass() ;

baseClass^ base_child_ptr = child ;

base_child_ptr->func() ; // execute base version!
}

-cd
 
P

Peter Oliphant

Yup, it was, of course, an entirely different problem (geee, has that ever
happened to anyone else before?)...ROFL

[==P==]

Carl Daniel said:
Peter Oliphant said:
Maybe I'M missing something, but this is what I'm experiencing:
[ code snipped ]
At least I think this is what I'm experiencing, typo I haven't noticed
not withstanding... : )

No, that definitely will execute the derived class version. Add some
Console.WriteLine's (or Trace or whatever) to the two functions to see for
sure.

using namespace System;

ref class baseClass
{
public:
baseClass() {}
~baseClass() {}

public:
virtual void func() { Console::WriteLine("Base version"); }
} ;

ref class childClass : public baseClass
{
public:
childClass() {}
~childClass() {}

public:
virtual void func() override { Console::WriteLine("Derived version"); }
} ;

int main()
{
childClass^ child = gcnew childClass() ;

baseClass^ base_child_ptr = child ;

base_child_ptr->func() ; // execute base version!
}

-cd
 
W

Willy Denoyette [MVP]

Carl Daniel said:
This is just basic polymorphism, as implemented by virtual functions in
both native C++ and .NET.

Simply declare the function virtual in the base class and override it in
the derived class(es). Calls through a pointer (or reference) to the base
class will in fact call the implementation supplied by the derived class.

If you don't want an implementation in the base class, declare it "pure"
(=0) in native C++, or abstract in .NET, otherwise you'll have to supply a
definition of the function in the base class as well.

-cd

Not directly related to OP's problem, but a good to know is that C++ allows
you to call the base class implementation like in following sample, however
this generates unverifiable code (run Peverify on the exe image to see the
error message).

// Compile with /clr:safe

using namespace System;

ref class A
{
public:
virtual void f()
{
Console::WriteLine("A::f");
}

};
ref class B : public A
{
public:
virtual void f() override
{
Console::WriteLine("B::f");
}
};

int main()
{

B b;
b.f();
b.A::f(); // ------> Call the Base class function
return 0;
}

Willy.
 
P

Peter Oliphant

Just tested that you can call base method from derived instance like you
described....very cool! : )

[==P==]
 

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

Top