views:

1214

answers:

4

I am trying to work on a homework assignment for school and am going above what the teacher is asking for the assignment -> I have created a "list" class. I keep running into these two errors after adding the 'add()' method to the program - along with the 'newIncomeTax()' methods

error LNK2019: unresolved external symbol "public: void __thiscall List::add(class IncomeTax *)" (?add@List@@QAEXPAVIncomeTax@@@Z) referenced in function _main driver.obj

and

fatal error LNK1120: 1 unresolved externals

I hope this will be enough code for anyone trying to help me:

note: the functions below are not in the order that they appear in the original code (if that may be the problem I can provide all the code that i'm using)

list.h

#ifndef LIST_H
#define LIST_H

#include "IncomeTax.h"
class List
{
private:
    IncomeTax * First;
    IncomeTax * Last;
    int num_in_list;
public:
    List () { num_in_list = 0; First = NULL; Last = NULL; }
    int get_num_in_list() { return num_in_list; }
    IncomeTax * getFirst() { return First; }
    IncomeTax * getLast() { return Last; }
    void del_frnt ();
    void push_front (IncomeTax *);
    void push_back (IncomeTax *);
    void del_last ();
    void add (IncomeTax*);
    IncomeTax * pop_back ();
    IncomeTax * pop_front ();
    IncomeTax * get (int);
};
#endif

note: from what I've seen the list that **I've** made behaves similarly to the default

the 'add' method from list.cpp

void List:: add (IncomeTax * IncomeTax_to_be_added) {
    if (num_in_list == 0) { First = IncomeTax_to_be_added; Last = IncomeTax_to_be_added; }
    else if (num_in_list != 0 ) {
        Last->setNext(IncomeTax_to_be_added);
        IncomeTax_to_be_added->setPrevous(Last);
        Last = IncomeTax_to_be_added;
    }
    num_in_list++;
}

IncomeTax.h

#ifndef INCOME_TAX
#define INCOME_TAX

#include <iostream>
#include <string>
#include "conio.h"
#include <cassert>
using namespace std;

class IncomeTax {
private:
    double incm;
    double ajIncm;
    double subtract;
    double taxRate;
    double add;
    bool married;

    void calcIncome_m ();
    void calcIncome_s ();
public:
    IncomeTax () { incm = 0; subtract = 0; taxRate = 0; add = 0; add = false; }
    // married -> is by default false
    void setmarried ( bool stats ) { married = stats; }
    void setIncm (double in ) { incm = in; }
    void setSubtract ( double sub ) { subtract = sub; }
    void setTaxRate ( double rate ) { taxRate = rate; }
    void setAdd ( double Add ) { add = Add; }
    void setAjIncome ( double AJincome ) { ajIncm = AJincome; }

    bool getmarried () { return married; }
    double getIncm () { return incm; }
    double getsubtract () { return subtract; }
    double getTaxRate () { return taxRate; }
    double getAdd () { return add; }
    double getAJincome () { return ajIncm; }
    void calcIncome ();
    void pintIncome ();
};

#endif

IncomeTax.cpp

#include "IncomeTax.h"
using namespace std;

void IncomeTax::calcIncome(){
    assert (incm != 0);
    if (married) { calcIncome_m(); }
    if (!married) { calcIncome_s(); }

    ajIncm = (incm - subtract);
    ajIncm -= (ajIncm * taxRate);
    ajIncm += add; 
}

void IncomeTax::calcIncome_m() {
    assert (incm != 0);
    ... huge nested if statements ... 
    they set subtract, add, taxRate...
}

void IncomeTax::calcIncome_s() {
    assert (incm != 0);
    ... huge nested if statements ... 
    they set subtract, add, taxRate...
}

void IncomeTax::pintIncome () {
    assert (incm != 0);
    assert (ajIncm != 0);

    std::cout.precision(2);
    cout << "\tTaxable Income: " << incm << endl;
    cout << "\tAjusted Income: " << ajIncm << endl;
    cout << "\tTax: " << (incm - ajIncm) << "\n" << endl;
}

Driver.cpp

#include <conio.h>
#include <iostream>
#include <string>
#include <cassert>
#include "IncomeTax.h"
#include "List.h"
using namespace std;

void getMaritalStatus( IncomeTax new_tax) {
    bool done = false;
    char stt = ' ';
    while ( !done ) {
        cout << "\nPlease declare weather you are filing taxes jointly or single" << "\n";
        cout << "\t's' = single\n\t'm' = married" << endl;
        stt = getch();
        if ( stt == 's' || stt == 'm' ) { done = true; }
        if ( stt == 's' ) { new_tax.setmarried(true); }
        if ( ! (stt == 's' || stt == 'm') ) { cout << "\nyou have entered an invald symbol... \n" << endl; }
        if(cin.fail()) { cin.clear(); }
        }
    }


void get_Income ( IncomeTax new_tax) {
    double _incm = 0;
    char status = ' ';
    bool done = true;
    while ( done ) {
        cout << "Please enter your TAXABLE INCOME:" << endl;
        cin >> _incm;
        if ( _incm > 0 ) { new_tax.setIncm(_incm); done = false; }
        if ( _incm <= 0 ) { cout << "\nthe number you entered was less than zero\nplease enter a valad number...\n" << endl; } 
        if(cin.fail()) { cin.clear(); }
    }
    }

IncomeTax newIncomeTax () {
    IncomeTax new_tax;
    IncomeTax * temp;
    get_Income(new_tax);
    getMaritalStatus(new_tax);
    new_tax.calcIncome();
    return new_tax;
}

bool again () {
    bool done = false, answer = false;
    char yn = ' ';
    while ( !done ) {
        cout << "\nWould you like to calculate another Income tax? (y/n)" << endl;
        yn = getch();
        if ( yn == 'y' || yn == 'n' ) { done = true; }
        if ( yn == 'y' ) { return false; }
        if ( yn == 'n' ) { return true; }
        if ( ! (yn == 's' || yn == 'n') ) { cout << "\nyou have entered an invald symbol... \n" << endl; }
        if(cin.fail()) { cin.clear(); }
        }
    }

int main () {
    IncomeTax new_tax;
    List L;
    bool done = false;
    while (!done) {
        IncomeTax temp = newIncomeTax();
        IncomeTax * ptr = &temp;
        L.add(ptr);
        done = again();
        };

    return 0;
};

I know that there are many better ways to do the 'if' statements -> i just decided that it would be efficient to just use the if statments -> the professor has stated that there is no need to go beyond this.

Since this is homework I would love to get some feed back on ways that I can use better programing techniques. thanks!

I'm using VS express 2008 C++

+1  A: 

Since this is homework I would love to get some feed back on ways that I can use better programing techniques. thanks!

Create separate headers/implementation files for your classes. Don't put all of them in a single header. And put your main in a separate implementation file (call it main.cpp, if you will).

Cut out all the functions that you are not using, and try to create the minimal example that reproduces your error -- that'll help you figure out your issues easily and without needing to come back to SO every now and then. Add one function at a time and see if it compiles, then move on to the next, rinse and repeat.

Another good idea when adding functions is to use stubs -- empty functions just to check if you don't hit any of these unresolved symbol errors (when you're starting out).

You will also need to learn about the syntax -- you don't need a semi-colon after the ending brace of while. You will also learn that members are initialized in the order in which they are declared (so your int member should ideally follow your IncomeTax members). You will need to know what initializer-lists are. And you will need to know about forward declaring.

In short, you will need a book and lots of practice. Here's your code refactored a bit using some of the things I explained above:

class IncomeTax {};

class List
    {
    private:
        IncomeTax * First;
        IncomeTax * Last;
        int num_in_list;
    public:
        List () : 
            First(NULL), 
            Last(NULL),
                        num_in_list (0)
        {}
        ~List() 
        {
            // free First and Last ?
        }
        void add (IncomeTax*) {}    
};

    int main () {
        IncomeTax new_tax;
        List L;
        bool done = false;
        while (!done) {
            IncomeTax temp;
            L.add(&temp);
                done = true;
        }

        return 0;
    }
dirkgently
oh, yeah, i've got all the class stuff in the respective .cpp and .h files - with the adding functions-> that's what I've been doing but that's when i ran into this error
Wallter
@Walter: Can you cut down your code and try to reproduce the problem -- see my updated post for ideas.
dirkgently
@dirkgently: the problem with that is that when i get these errors they don't have a line number... except '1' - which is a comment that I wrote the code --- the code i provided is the code i was editing when i got the error
Wallter
@Walter: Your problem could be as simple as a typo. E.g: Look at `IncomeTax::pintIncome()` -- you probably declared a `printIncome()` method in the header! Check for spellings.
dirkgently
A: 

There's something else you're not telling us here since this should link flawlessly (it did here). I just moved the List class declaration before main() to avoid the class is declared when compiling main but otherwise everything compiles fine.

// Something declared in this order (in the same file or through .h files) should compile & link correctly
class IncomeTax { ... };
class List { ... };
int main() { ... };
Francis Boivin
my declarations for driver.cpp (contains main) go like this: #include <iostream> #include <string> #include <cassert> #include "IncomeTax.h" #include "List.h" using namespace std; so i don't think that's the problem... but it might
Wallter
A: 

It looks like you may have forgotten to add the IncomeTax object file (IncomeTax.o, IncomeTax.obj, etc) into your link command line, and the linker is telling you that it can't find the method definition.

You can test this by temporarily creating a single "whole_project.cpp" file that contains all the code copy-pasted sequentially. If it compiles and links correctly that way, then you just need to edit your makefile/IDE project file/manual command line to specify that it also needs to include the object file.

It only shows the one error because you're only actually calling the add function and none of the other non-inline functions within the list class.

Finally, double check the logic you're using to add items to the list. I believe the temporary you're adding will cause problems since the object goes away as soon as the while loop enters its next iteration.

Mark B
A: 

*nvm should still work

Exploit
You should be able to delete your own post, if you want, btw. Look for the "delete" link under the answer text (above this comment), to the left.
Roger Pate