I use a parent class which has some virtual methods. When I call the virtual method in the constructor, it gives LNK2019
and LNK1120
errors with "error LNK2019: unresolved external symbol "protected: virtual int ... referenced in function "public: __thiscall ...
" and "...\Debug\8puzzleProject.exe : fatal error LNK1120: 1 unresolved externals
" messages.
Is there way to solve this problem or shoudn't I call a virtual method in the constructor?
Thank you!
Here is the codes:
Class with errors:
#ifndef HEURISTICSEARCH_H
#define HEURISTICSEARCH_H
#include "BruteSearch.h"
class HeuristicSearch: public BruteSearch
{
public:
HeuristicSearch( int initial[BOARD_LIMIT][BOARD_LIMIT] );
bool search();
protected:
virtual int calculateUtility() = 0;
virtual int calculateUtility( Node* ) = 0;
bool check4Goal();
void checkNmove();
int findMin(int* values );
int utilityCost;
};
#endif
HeuristicSearch::HeuristicSearch( int initial[BOARD_LIMIT][BOARD_LIMIT] )
:BruteSearch( initial )
{
utilityCost = calculateUtility(); //After deleting this line, the error's gone
}
Parent class of the parent class (There is no error)
#ifndef BRUTESEARCH_H
#define BRUTESEARCH_H
#include <iostream>
#include <queue>
#include "Constants.h"
#include "Node.h"
class BruteSearch
{
public:
BruteSearch( int initial[BOARD_LIMIT][BOARD_LIMIT] );
virtual bool search(){ return false; }
protected:
bool check4Goal();
void printBoard();
int turn;
int goalBoard[BOARD_LIMIT][BOARD_LIMIT] ;
Node *currentPtr;
};
#endif
shoudn't I call a virtual method in the constructor?
Doing so will call the override in the class being constructed, not necessarily the final override. This is probably not what you want, and an error if the function is pure virtual in the current class, so generally you shouldn't.
In this case, the error suggests that it's pure virtual, and not implemented, in this class, so calling it is definitely an error. Luckily, it gave you a reasonably friendly linker error rather than undefined runtime behaviour. (UPDATE: the code you've posted confirms that guess - you can't call the function from the constructor).
Is there way to solve this problem
Many problems can be solved with an extra level of indirection. I would implement the heuristic in a separate delegate class, rather than a subclass:
struct Heuristic {
virtual ~Heuristic() {} // Don't forget this on a polymorphic base class
virtual int calculateUtility() = 0;
virtual int calculateUtility( Node* ) = 0;
};
class HeuristicSearch: public BruteSearch {
public:
HeuristicSearch(Heuristic & h, int initial[BOARD_LIMIT][BOARD_LIMIT]) :
BruteSearch(initial),
heuristic(h),
utilityCost(heuristic.calculateUtility()) // No problem calling this
{}
private:
Heuristic & heuristic;
int utilityCost;
// and so on
};
The delegate is fully constructed before we start to construct the Search class, so there are no issues accessing it from the constructor.
Alternatively, to avoid unnecessary runtime polymorphism, I might inject the delegate type as a template parameter:
template <class Heuristic>
class HeuristicSearch: public BruteSearch {
public:
HeuristicSearch(int initial[BOARD_LIMIT][BOARD_LIMIT]) :
BruteSearch(initial),
utilityCost(heuristic.calculateUtility()) // Doesn't have to be virtual
{}
private:
Heuristic heuristic;
int utilityCost;
// and so on
};