Problems understanding C ++ `virtual`

I am having trouble understanding the purpose of a keyword virtualin C ++. I know C and Java very well, but I'm new to C ++

From Wikipedia

In object-oriented programming, a virtual function or virtual method is a function or method whose behavior can be redefined as a legacy class using a function with the same signature.

However, I can override the method as shown below without using the keyword virtual

#include <iostream>

using namespace std;

class A {
    public:
        int a();
};

int A::a() {
    return 1;   
}

class B : A { 
    public:
        int a();
};

int B::a() {
    return 2;
}

int main() {
    B b;
    cout << b.a() << endl;
    return 0;
}

//output: 2

As you can see below, the function A :: a is successfully redefined by B :: a, without requiring virtual

The combination of my confusion is a statement about virtual destructors, also from wikipedia

, ++ .

, virtual ? , -, virtual " "

+5
9

, , :

#include <iostream>

using namespace std;

class A {
    public:
        int a();
};

int A::a() {
    return 1;   
}

class B : public A { // Notice public added here
    public:
        int a();
};

int B::a() {
    return 2;
}

int main() {
    A* b = new B(); // Notice we are using a base class pointer here
    cout << b->a() << endl; // This will print 1 instead of 2
    delete b; // Added delete to free b
    return 0;
}

, , :

#include <iostream>

using namespace std;

class A {
    public:
        virtual int a(); // Notice virtual added here
};

int A::a() {
    return 1;   
}

class B : public A { // Notice public added here
    public:
        virtual int a(); // Notice virtual added here, but not necessary in C++
};

int B::a() {
    return 2;
}

int main() {
    A* b = new B(); // Notice we are using a base class pointer here
    cout << b->a() << endl; // This will print 2 as intended
    delete b; // Added delete to free b
    return 0;
}

, , . , , , A, B . , ? : , a(), .

+16

.

Java . , , .

++, , .

Base Derived, 'foo',

Base * base;
Derived *derived;

base->foo(); // calls Base::foo
derived->foo(); // calls Derived::foo

foo , Derived:: foo.

+9

virtual , , , , . , , B, , .

+2

, virtual ? , , " "

.

  • ( ) . , , , -.
  • . .

"" , " ". , .

a pointer-to-A, A* a;, --A, -to -B, B A.

A* a; 
B* b;

b = new B(); // create a object of type B. 
a = b;       // this is valid code. a has still the type pointer-to-A, 
             // but the value it holds is b, a pointer to a B object.

a.a();       // now here is the difference. If a() is non-virtual, A::a()
             // will be called, because a is of type pointer-to-A. 
             // Whether the object it points to is of type A, B or
             // something entirely different doesn't matter, what gets called
             // is determined during compile time from the type of a.

a.a();       // now if a() is virtual, B::a() will be called, the compiler
             // looks during runtime at the value of a, sees that it points
             // to a B object and uses B::a(). What gets called is determined
             // from the type of the __value__ of a.
+2

, A:: a B:: a,

, . , , B , A. . ++ FAQ Lite, 20.3.

, ?

, , , , , . . ++ FAQ Lite, 20.7.

+1

, consultutah ( , ;)) .

, , ( - ). , .

, (.. "" ), .

, , ++ , , , java, ( ), , , . , ( "A a" "A * a = new A();" ), . , , / , , - .

+1

((A *) & b).a() , .

(I.E. ) ...

, " ". , A, B newer a().

0

, B, A:

A *a = new B();

a(), () ?

a() , . a() , a() , .

B ,

delete a;

, B- , , - .

.

0
source

I always think of it as chess (my first experiment with OO).

A chessboard contains pointers to all the pieces. Empty squares are NULL pointers. But all he knows is that each pointer points to a chess piece. The council does not need to know more information. But when a piece moves, the board does not know that this is a real move, since each point has a different characteristic about how it moves. Therefore, the board should be checked together with a piece, if this action is valid.

Piece*    board[8][8];

CheckMove(Point const& from,Point const& too)
{
    Piece*  piece = board[from.x][from.y];
    if (piece != NULL)
    {
        if (!piece->checkValidMove(from,too))
        {    throw std::exception("Bad Move");
        }
        // Other checks.
    }
}

class Piece
{
    virtual bool checkValidMove(Point const& from,Point const& too)  = 0;
};

class Queen: public Piece
{
    virtual bool checkValidMove(Point const& from,Point const& too) 
    {
         if (CheckHorizontalMove(from,too) || CheckVerticalMoce(from,too) || CheckDiagonalMove(from,too))
         {
             .....
         }
    }
}
0
source

All Articles