calling virtual methods from ctor 
Author Message
 calling virtual methods from ctor

hi !

I have small question. Please read line marked with #HERE

using System;

public class Human

{

protected int age;

public Human(int age)

{

this.age = age;

//#HERE

print(); //this will call Man::print() in my example. how to force compiler
to call Human::print() instead? this.print() doesn't make any difference

Quote:
}

public virtual void print()

{

Console.WriteLine("I'm Human");

Quote:
}
}

public class Man : Human

{

public Man() : base(21)

{

Quote:
}

public override void print()

{

Console.WriteLine("I'm a Man, " + age.ToString() + " years old!");

Quote:
}
}

public class ConsoleApp

{

public static void Main(string[] arg)

{

Human david = new Man();

Console.ReadLine();

Quote:
}
}



Tue, 01 Mar 2005 05:01:58 GMT  
 calling virtual methods from ctor
David,

Quote:
>//#HERE

>print(); //this will call Man::print() in my example. how to force compiler
>to call Human::print() instead? this.print() doesn't make any difference

You can't do that. If you want to ensure that code in the Human class
runs, make the method non virtual.

Mattias

===

http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.



Tue, 01 Mar 2005 04:36:35 GMT  
 calling virtual methods from ctor
Don't mark the Print method virtual in class Human and mark the Print
method in Man with the keyword new.

Frankly, I'm surprised it does this, because until the Human
constructor returns to the Man constructor, the Man object is not
fully created, and so shouldn't be able to call any overridden methods
in the derived class.  In C++, I don't think it would do this, but I'd
have to try it out to be 100% sure.

Jonathan Schafer

On Thu, 12 Sep 2002 22:01:58 +0100, "David Krmpotic"

Quote:

>hi !

>I have small question. Please read line marked with #HERE

>using System;

>public class Human

>{

>protected int age;

>public Human(int age)

>{

>this.age = age;

>//#HERE

>print(); //this will call Man::print() in my example. how to force compiler
>to call Human::print() instead? this.print() doesn't make any difference

>}

>public virtual void print()

>{

>Console.WriteLine("I'm Human");

>}

>}

>public class Man : Human

>{

>public Man() : base(21)

>{

>}

>public override void print()

>{

>Console.WriteLine("I'm a Man, " + age.ToString() + " years old!");

>}

>}

>public class ConsoleApp

>{

>public static void Main(string[] arg)

>{

>Human david = new Man();

>Console.ReadLine();

>}

>}



Tue, 01 Mar 2005 05:54:12 GMT  
 calling virtual methods from ctor
David... To ensure that the "proper" print method is called, calling
((Human)man).print() still calls Man.print(). This is the behaviour of
overrides, allowing you to store men and women in a collection of Humans
and call objectInCollection.print() automagically calling the print
method in Man or Woman as appropriate.

If this is not the behavior you need, check out new, which hides the
Human behaviour with the same signature and return type.

public class Human
{
        public const bool IS_DEBUG= true;
        private int age= 0;

        public Human(int age)
        {
                this.age = age;
                if (IS_DEBUG)
                {
                        System.Console.WriteLine("Human constructed.");
                }
        }
        public virtual void Print()
        {
                Console.WriteLine("I'm Human aged: "+ age.ToString());
        }

Quote:
}

public class Man : Human
{
        private int numFishingPoles= 0;
        public Man(int age) : base(age)
        {
                if (IS_DEBUG)
                {
                        System.Console.WriteLine("Man constructed.");
                        }
        }
        public new void Print()
        {
                Console.WriteLine("I'm a Man with fishing poles: "+
numFishingPoles.ToString());
        }
        public static void Main(string[] args)
        {
                Man man= new Man(21);
                man.Print();
                ((Human)man).Print();
                Console.ReadLine();
        }

Quote:
}

Regards,
Jeff
Quote:
>print(); //this will call Man::print() in my example. how to force

compiler to call Human::print() instead? this.print() doesn't make any
difference<

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!



Tue, 01 Mar 2005 06:01:46 GMT  
 calling virtual methods from ctor
Replying to my own post :(

In fact, I wrote a small C++ program to do this, and as I suspected,
calling Print() in the Human class constructor will NOT call the
overridden Print() in the Man class, because the class has not been
fully initialized yet.

The way C# handles this is definitely different than C++.  I don't
know that it is a bug, but clearly the order of construction and
virutal method calls is completely different than C++ in this regard.

Jonathan Schafer

On Thu, 12 Sep 2002 16:54:12 -0500, Jonathan Schafer

Quote:

>Don't mark the Print method virtual in class Human and mark the Print
>method in Man with the keyword new.

>Frankly, I'm surprised it does this, because until the Human
>constructor returns to the Man constructor, the Man object is not
>fully created, and so shouldn't be able to call any overridden methods
>in the derived class.  In C++, I don't think it would do this, but I'd
>have to try it out to be 100% sure.

>Jonathan Schafer

>On Thu, 12 Sep 2002 22:01:58 +0100, "David Krmpotic"

>>hi !

>>I have small question. Please read line marked with #HERE

>>using System;

>>public class Human

>>{

>>protected int age;

>>public Human(int age)

>>{

>>this.age = age;

>>//#HERE

>>print(); //this will call Man::print() in my example. how to force compiler
>>to call Human::print() instead? this.print() doesn't make any difference

>>}

>>public virtual void print()

>>{

>>Console.WriteLine("I'm Human");

>>}

>>}

>>public class Man : Human

>>{

>>public Man() : base(21)

>>{

>>}

>>public override void print()

>>{

>>Console.WriteLine("I'm a Man, " + age.ToString() + " years old!");

>>}

>>}

>>public class ConsoleApp

>>{

>>public static void Main(string[] arg)

>>{

>>Human david = new Man();

>>Console.ReadLine();

>>}

>>}



Tue, 01 Mar 2005 07:30:38 GMT  
 calling virtual methods from ctor

Quote:

> Replying to my own post :(

> In fact, I wrote a small C++ program to do this, and as I suspected,
> calling Print() in the Human class constructor will NOT call the
> overridden Print() in the Man class, because the class has not been
> fully initialized yet.

> The way C# handles this is definitely different than C++.  I don't
> know that it is a bug, but clearly the order of construction and
> virutal method calls is completely different than C++ in this regard.

Not a bug.  Much like the rest of C#, it is the same as the behavior in
Java.  The bottom line is that constructors shouldn't call virtual
methods.  The perceived need to do so is typically a problem with the
design.

In the example code provided, there is no reason to ever call print()
from the constructor (except perhaps for debugging purposes).  Perhaps
the original poster can provide some code that better explains the problem.

Jim S.



Tue, 01 Mar 2005 23:53:04 GMT  
 calling virtual methods from ctor


Quote:

>> Replying to my own post :(

>> In fact, I wrote a small C++ program to do this, and as I suspected,
>> calling Print() in the Human class constructor will NOT call the
>> overridden Print() in the Man class, because the class has not been
>> fully initialized yet.

>> The way C# handles this is definitely different than C++.  I don't
>> know that it is a bug, but clearly the order of construction and
>> virutal method calls is completely different than C++ in this regard.

>Not a bug.  Much like the rest of C#, it is the same as the behavior in
>Java.  The bottom line is that constructors shouldn't call virtual
>methods.  The perceived need to do so is typically a problem with the
>design.

No, I'm sure it isn't, because that would be a very large one.
However, I never heard anything about this change, so it took me by
surprise a bit.  Still, I don't call virtual methods in my base class
constructors, so its not a problem for me anyway.

Quote:
>In the example code provided, there is no reason to ever call print()
>from the constructor (except perhaps for debugging purposes).  Perhaps
>the original poster can provide some code that better explains the problem.

>Jim S.

I agree, although it could be that he was simply trying to see how
things worked, and maybe it was not a real world example.

Jonathan Schafer



Wed, 02 Mar 2005 02:32:38 GMT  
 calling virtual methods from ctor

<snip>

Quote:

> No, I'm sure it isn't, because that would be a very large one.
> However, I never heard anything about this change, so it took me by
> surprise a bit.  

There is great danger in looking at a new language as an old language
with 'changes'.  Lots of little pitfalls.  Reading the langauge
specification from cover to cover can be extremely helpful.

<snip>

Quote:

> I agree, although it could be that he was simply trying to see how
> things worked, and maybe it was not a real world example.

Sure.  I was hoping to see some examples to exercise the 'ol brain a bit
on how to do things 'right'.

Jim S.



Wed, 02 Mar 2005 03:21:31 GMT  
 calling virtual methods from ctor
yes, I only wanted to see how things works. I know it's a bad idea to
call virtual methods from ctor, because object is not yet instantiated
and class properties/variables are still set to default value at the
time of the call.

Thank you! I can see clearly now :)

David



Thu, 03 Mar 2005 20:39:32 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Virtual Method Calls

2. Class ctor for class with Main method

3. std::bad_alloc ctor calls malloc????

4. Smart calls of ctors & destructors

5. string range ctor not getting called.

6. Multiple inheritance - calling ctors

7. Dynamic Method call ( Invoke method ) failing in service when compiled as ReleaseMinDependancy

8. calling an interface method from another method in the same class

9. Calling a method from within a method, legal?

10. Calling a COM call back object's method fails if it is in Windows 98

11. Bool return type from virtual method

12. VS .NET Does Not Complain When Pure Virtual Method Isn't Defined

 

 
Powered by phpBB® Forum Software