How can I find the cause of this incredibly cryptic linker error?

306 Views Asked by At

I am working on a calculator for RPN expressions and I am getting a linker error that I can't seem to resolve. I am trying to use a double dispatch in order to choose the correct operation and value. I will start at the top of the class hierarchy and move downwards until Operand is reached. It is not derived from operator.

integer.obj : error LNK2001: unresolved external symbol "public: virtual class std::shared_ptr<class Operand> __thiscall Operand::perform_addition(class std::vector<class std::shared_ptr<class Token>,class std::allocator<class std::shared_ptr<class Token> > > &)" (?perform_addition@Operand@@UAE?AV?$shared_ptr@VOperand@@@std@@AAV?$vector@V?$shared_ptr@VToken@@@std@@V?$allocator@V?$shared_ptr@VToken@@@std@@@2@@3@@Z)
tokenizer.obj : error LNK2001: unresolved external symbol "public: virtual class std::shared_ptr<class Operand> __thiscall Operand::perform_addition(class std::vector<class std::shared_ptr<class Token>,class std::allocator<class std::shared_ptr<class Token> > > &)" (?perform_addition@Operand@@UAE?AV?$shared_ptr@VOperand@@@std@@AAV?$vector@V?$shared_ptr@VToken@@@std@@V?$allocator@V?$shared_ptr@VToken@@@std@@@2@@3@@Z)
ut_rpn_evaluator.obj : error LNK2001: unresolved external symbol "public: virtual class std::shared_ptr<class Operand> __thiscall Operand::perform_addition(class std::vector<class std::shared_ptr<class Token>,class std::allocator<class std::shared_ptr<class Token> > > &)" (?perform_addition@Operand@@UAE?AV?$shared_ptr@VOperand@@@std@@AAV?$vector@V?$shared_ptr@VToken@@@std@@V?$allocator@V?$shared_ptr@VToken@@@std@@@2@@3@@Z)
tokenizer.obj : error LNK2001: unresolved external symbol "public: virtual class std::shared_ptr<class Operand> __thiscall Operation::perform(class std::vector<class std::shared_ptr<class Token>,class std::allocator<class std::shared_ptr<class Token> > > &)" (?perform@Operation@@UAE?AV?$shared_ptr@VOperand@@@std@@AAV?$vector@V?$shared_ptr@VToken@@@std@@V?$allocator@V?$shared_ptr@VToken@@@std@@@2@@3@@Z)
C:\Users\User\OneDrive\School\Semester 3\Course\project\Debug\ut_rpn_evaluator.exe : fatal error LNK1120: 2 unresolved externals

The definition of these functions starts here at the base class:

class Operation : public Token {
public:
    using pointer_type = TOKEN_PTR_TYPE(Operation);
    virtual unsigned number_of_args() const = 0;
    virtual Operand::pointer_type perform( TokenList& params );
};

The next derived class is Operator and then Addition in Operator header:

class Addition : public LAssocOperator {
    DEF_IS_CONVERTABLE_FROM(Addition)
    DEF_PRECEDENCE(ADDITIVE)
    public:
        Operand::pointer_type perform(TokenList& params);
    };

This is my implementation in the source code file for operator:

Operand::pointer_type Addition::perform(TokenList& param){
    Operand::pointer_type op;
        op = op->perform_addition(params);
    return op;

}

This is the declaration of the function in the operand header file:

class Operand : public Token
{
public:
    using pointer_type = TOKEN_PTR_TYPE(Operand);

    //Operation Definitions
    virtual Operand::pointer_type perform_addition(TokenList& params);
};

Integer derives from operand and this is part of the class definition in the header:

class Integer : public Operand {
public:
    //usings for pointer and value
private:
    //member for value
public:
    //Constructor
    value_type              get_value() const { return value_; }

        Operand::pointer_type perform_addition(TokenList& params);
};

Finally, I end up defining the function in the integer source file:

Operand::pointer_type Integer::perform_addition(TokenList& params){
    Integer::value_type value = Integer::value_type(0);
    for (auto val : params){
        value += convert<Integer>(val)->get_value();
    }
    return make_operand<Integer>(value);
}

I have been reading a lot of material on the C++ linker and linker errors, yet I can't figure this out. I'm always getting linker errors for stupid things I'm doing. Can anyone spot an issue?

Thanks

1

There are 1 best solutions below

1
On BEST ANSWER
class Operand : public Token
{
    // ....
    virtual Operand::pointer_type perform_addition(TokenList& params);

This method has not been implemented anywhere. If you meant for it to be pure virtual then you need to add = 0 at the end.