Jump to content

Virtual problem


Holloweye
 Share

Recommended Posts

I have a problem with virutal function.

 

Board.h

#include "Knight.h"

class Board

{

//Board hava a array with Pieces

};

 

Piece.h

class Piece

{

virtual void move()

{

blablabla

};

};

 

Knight.h

#include "Piece.h"

Knight: public Piece

{

void move()

{

blablabla

};

}:

 

...

 

 

 

So when I try this inside a function or whatever in board.cpp:

Pieces[0].move();

 

it will use the Piece move() not the Knight's move(). Anyone understand why? :S

Link to comment
Share on other sites

Generally what you do is:

 

Piece* p = new Knight();

 

p->Move(); // this would call the Knight's Move() method. You would do this because you want a list of Piece objects, but you want a common method to call child methods of the same name because they'll act differently.

 

You chess example is a perfect example of this. You have the parent Piece which has a virtual Move() function. I would make Piece Move() a pure virtual (virtual void Move() = 0). You would want this because you wouldn't want a Piece object to be created. Instead you want it's children to be created. There is no such thing as a generic piece. It has to a specific piece (child).

 

So in closing

class Piece
{
public:
  virtual void Move()=0;
};


class Knight : public Piece
{
public:
  virtual void Move() {}
};

Piece* p = new Knight();

p->Move();

 

Ideally you will create a list or vector of Piece pointers like:

 

list<Piece*> p;

p.push_back(new Knight());

Link to comment
Share on other sites

I almost agree with Rick:

Putting a method virtual means you are overriding it somewhere. You are inheriting from piece, and overriding the method Move in that class. But you don't want to inherited from Knight, so you won't override the method again, so don't make it virtual.

Me, reading the code from Rick, am thinking you are going to override Move again in an inherited class from Piece.

 

Behind the screens this method will be virtual, but don't mind that. Try to code what you mean.

Link to comment
Share on other sites

Behind the screens this method will be virtual, but don't mind that. Try to code what you mean.

 

That's generally why I just always put virtual on the child functions. Like you said in this example he wouldn't derive and override Knight:Move(), but I generally do that do I know when looking at Knight that this function is virtual and most likely the parent one is also.

Link to comment
Share on other sites

That's generally why I just always put virtual on the child functions. Like you said in this example he wouldn't derive and override Knight:Move(), but I generally do that do I know when looking at Knight that this function is virtual and most likely the parent one is also.

I agree with TheoLogic; no point in creating more virtual function tables than necessary. Just make a comment if you want to know it is a virtual function.

 

*edit*

Misspelled TheoLogic's name.

Windows 7 64-bit

nVidia 9800M GS

4 GB RAM

Intel Core 2Duo, P8600 @ 2.4GHz

Link to comment
Share on other sites

I agree with TheoLogic; no point in creating more virtual function tables than necessary. Just make a comment if you want to know it is a virtual function.

 

Behind the screens this method will be virtual, but don't mind that. Try to code what you mean.

 

It doesn't matter because it's virtual anyway. So really by not putting virtual on child classes I think it just hides the fact that this overrides a base class method.

 

The below code will call MyKnights::Move() over though I don't have virtual on the Move() functions for Knight or MyKnight. No need in hiding this fact by not putting virtual.

 


class Piece
{
public:
virtual void Move()=0;
};

class Knight : public Piece
{
public:
void Move()
{
}
};

class MyKnight : public Knight
{
public:
void Move()
{// this is
}
};

int main()
{
Piece* p = new MyKnight();

p->Move();

return 0;
}

Link to comment
Share on other sites

I would do it like this:

#include <iostream>
#include <vector>
using namespace std;

enum PieceType {Knight,King};

string GetPieceTypeName(PieceType t)
{
switch(t)
{
	case Knight: return "Knight"; break;
	case King  : return "King"; break;
	default: return "Piece"; break;
}
}

class Piece
{
PieceType type;
public:
void SetType(PieceType t)
{
	type=t;		
}
PieceType GetType()
{
	return type;
}
void Move()
{
	cout << GetPieceTypeName(GetType()).c_str() << " moved." << endl;
}
};

int main()
{
vector<Piece> piece;
Piece newitem;

newitem.SetType(Knight);
piece.push_back(newitem);

newitem.SetType(King);
piece.push_back(newitem);

piece.at(0).Move();
piece.at(1).Move();

return 0;
}

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

@Rick: Depends on how the team's coding standards are. I'm working with type what you mean, but this is only one of bjarne stroustrup's C++ coding standards points.

 

And I agree, use stl containers for data handling. (vector > list) Use vector to iterate with algorithms, use map for searching (binary tree).

 

 

Right, but behind the scenes this is what's happening. It's not like you are saving storage space or anything by not putting virtual in front of the child overloaded function.

Link to comment
Share on other sites

It doesn't matter because it's virtual anyway. So really by not putting virtual on child classes I think it just hides the fact that this overrides a base class method.

 

The below code will call MyKnights::Move() over though I don't have virtual on the Move() functions for Knight or MyKnight. No need in hiding this fact by not putting virtual.

 

I did not know this! Good to know! :D

Windows 7 64-bit

nVidia 9800M GS

4 GB RAM

Intel Core 2Duo, P8600 @ 2.4GHz

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...