#include <iostream> class Base { public: void Print() { std::cout << 0; }; }; class Class : public Base { public: void Print() { std::cout << 1; }; }; void Print(Base c) { c.Print(); } int main() { Class *A = new Class(); Print(*A); return 0; } 

Why prints 0 instead of 1?

On java prints 1:

 class Base{ void f(){System.out.print(0);} } class Class extends Base{ void f(){System.out.print(1);} } public class Main { public static void g(Base x){ xf(); } public static void main(String[] args){ g(new Class()); } } 
  • You have a typo in the Java example. I think you had to output Base in class 0 instead of 1. - Vlad from Moscow

2 answers 2

In this ad function Print

 void Print(Base c) { c.Print(); } 

The parameter is of type Base . Accordingly, the compiler looks for the declaration of the Print function in the Base class and calls it.

In this function call

 Print(*A); 

The *A argument, of type Class converted to an object of type Base .

You could achieve a similar effect in a Java program if 1) a function parameter would be declared either as a pointer to a Base object or as a reference to a Base object, and the member function of the Print class would be declared as virtual.

In Java, objects are passed by reference, while in your example programs for C ++ objects are passed by value.

In this regard, C # is “in the middle” between C ++ and Java. That is, objects are passed by reference, but functions can be both virtual and non-virtual.

Java

 import java.util.*; import java.lang.*; import java.io.*; /* Name of the class has to be "Main" only if the class is public. */ class Base { void Print() { System.out.println( 0 ); } } class Class extends Base { void Print() { System.out.println( 1 ); } } class Ideone { static void Print( Base b ) { b.Print(); } public static void main (String[] args) throws java.lang.Exception { Print( new Class() ); } } 

Program output

 1 

C #

 using System; class Base { public void Print() { Console.WriteLine( 0 ); } } class Class :Base { public new void Print() { Console.WriteLine( 1 ); } } public class Test { static void Print( Base b ) { b.Print(); } public static void Main() { Print( new Class() ); } } 

Program output

 0 

Declaring a virtual function

 using System; class Base { public virtual void Print() { Console.WriteLine( 0 ); } } class Class :Base { public override void Print() { Console.WriteLine( 1 ); } } public class Test { static void Print( Base b ) { b.Print(); } public static void Main() { Print( new Class() ); } } 

Program output

 1 

C ++

 #include <iostream> class Base { public: void Print() { std::cout << 0 << std::endl; } }; class Class : public Base { public: void Print() { std::cout << 1 << std::endl; } }; void Print( Base b ) { b.Print(); } int main() { Class *A = new Class(); Print( *A ); delete A; return 0; } 

Program output

 0 

Declaring a virtual function and passing an object by reference

 #include <iostream> class Base { public: virtual void Print() { std::cout << 0 << std::endl; } }; class Class : public Base { public: void Print() override { std::cout << 1 << std::endl; } }; void Print( Base &b ) { b.Print(); } int main() { Class *A = new Class(); Print( *A ); delete A; return 0; } 

Program output

 1 

Declaring a virtual function and passing an object through the pointer

 #include <iostream> class Base { public: virtual void Print() { std::cout << 0 << std::endl; } }; class Class : public Base { public: void Print() override { std::cout << 1 << std::endl; } }; void Print( Base *b ) { b->Print(); } int main() { Class *A = new Class(); Print( A ); delete A; return 0; } 

Program output

 1 

As you can see from these examples, in C #, although objects are passed by reference, functions must nevertheless be virtual in order to achieve the same effect as in Java.

In C ++, it is necessary not only to declare functions virtual, but also to explicitly pass objects either by reference or through a pointer.

    Because virtuality in C ++ is not done by default. You need to explicitly declare the Print function virtual, and pass to

     void Print(Base c) 

    an object by reference (or by address, but not by value - this is a big mistake, which is fraught with the same cutoff ):

     class Base { public: virtual void Print() { std::cout << 0; }; }; class Class : public Base { public: void Print() { std::cout << 1; }; }; void Print(Base& c) { c.Print(); } int main() { Class *A = new Class(); Print(*A); return 0; } 

    As virtual , it is enough to declare a function only in the base class.

    • Congratulations, you already have 1000 answers :) - αλεχολυτ
    • Thank! Didn't even know :) - Harry