Holloweye Posted December 10, 2009 Share Posted December 10, 2009 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 Quote Link to comment Share on other sites More sharing options...
Canardia Posted December 10, 2009 Share Posted December 10, 2009 You are calling Piece::move() and not Knight::move(). Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Holloweye Posted December 10, 2009 Author Share Posted December 10, 2009 its virtual is should automaticly call knight::move() ... Pieces[0] = Knight(); Pieces[0].move(); // it will call the Piece move() Quote Link to comment Share on other sites More sharing options...
Canardia Posted December 10, 2009 Share Posted December 10, 2009 You need to declare the move method in Knight also as virtual. A good rule is: always declare all methods as virtual. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Holloweye Posted December 10, 2009 Author Share Posted December 10, 2009 No, parent classes don't call their child classes' methods. You can do it via a reference from the parent class though. so if it would be like this: Knight AKnight(); AKnight.move(); it would work? Quote Link to comment Share on other sites More sharing options...
TheoLogic Posted December 10, 2009 Share Posted December 10, 2009 @Lumooja, your are crazy. Every class with a virtual function has a virtual function table. You can as well code Java. You're loosing a pointer jump with every vft you have! @Holloweye: read this EDIT: don't forget the virtual destructor, copy constructor and assignment operator Quote Follow me Link to comment Share on other sites More sharing options...
Rick Posted December 10, 2009 Share Posted December 10, 2009 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()); Quote Link to comment Share on other sites More sharing options...
TheoLogic Posted December 10, 2009 Share Posted December 10, 2009 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. Quote Follow me Link to comment Share on other sites More sharing options...
Rick Posted December 10, 2009 Share Posted December 10, 2009 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. Quote Link to comment Share on other sites More sharing options...
graytest Posted December 10, 2009 Share Posted December 10, 2009 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. Quote Windows 7 64-bit nVidia 9800M GS 4 GB RAM Intel Core 2Duo, P8600 @ 2.4GHz Link to comment Share on other sites More sharing options...
Rick Posted December 10, 2009 Share Posted December 10, 2009 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; } Quote Link to comment Share on other sites More sharing options...
Holloweye Posted December 10, 2009 Author Share Posted December 10, 2009 I found the problem. It was that the Piece array need be a array with pointers to Piece's. So like this: Piece ***Pieces; (Its a matrix with Pieces) Thanks for the help Quote Link to comment Share on other sites More sharing options...
Rick Posted December 10, 2009 Share Posted December 10, 2009 I would strongly point you to use standard template libraries vector or lists. It can make things much easier. Quote Link to comment Share on other sites More sharing options...
TheoLogic Posted December 11, 2009 Share Posted December 11, 2009 @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). Quote Follow me Link to comment Share on other sites More sharing options...
Canardia Posted December 11, 2009 Share Posted December 11, 2009 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; } Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
TheoLogic Posted December 11, 2009 Share Posted December 11, 2009 Hehe, we can do this all day: Composition vs inheritence Quote Follow me Link to comment Share on other sites More sharing options...
Rick Posted December 11, 2009 Share Posted December 11, 2009 @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. Quote Link to comment Share on other sites More sharing options...
graytest Posted December 11, 2009 Share Posted December 11, 2009 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! Quote Windows 7 64-bit nVidia 9800M GS 4 GB RAM Intel Core 2Duo, P8600 @ 2.4GHz Link to comment Share on other sites More sharing options...
Recommended Posts
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.