1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Unresolved external symbol in class

Discussion in 'C++' started by thekevin07, Oct 7, 2008.

  1. thekevin07

    thekevin07 New Member

    Joined:
    Sep 13, 2008
    Messages:
    29
    Likes Received:
    0
    Trophy Points:
    0
    I can't get this to compile what am i doing wrong. This is just a simple class that represents dates (month day yr). I have a feeling what i am doing wrong has to do with the mynames portion both in date.h and date.cpp.



    error
    Code:
    1>date.obj : error LNK2001: unresolved external symbol "private: static char * * date::mnames" (?mnames@date@@0PAPADA)
    


    date.h
    Code:
    #pragma once
    #include "stdafx.h"
    #include <ostream>
    using namespace std;
    class date
    {
    	private:
    		int month;
    		int day;
    		int year;
    		static char *mnames[];
    
    	public:
    
    		friend ostream &operator<<(ostream &, const date &);
    
    		date(void);
    		date(int, int, int);
    		date(date &);
    		int getMonth();
    		int getDay();
    		int getYear();
    		static char *getMonthName(int i){return mnames[i];}
    		void setMonth(int m);
    		void setDay(int d);
    		void setYear(int y);
    		void printDate();
    		void printDateX();
    };
    
    date.cpp
    Code:
    #include <iostream>
    #include "date.h"
    
    static char *mnames[]= { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec" };
    
    date::date(void)
    {
    	day=1;
    	month=1;
    	year=1900;
    }
    
    date::date(int d, int m, int y)
    : day(d), month(m), year(y)
    {
    
    }
    
    void date::setMonth(int m)
    {
    	
    }
    
    void date::setDay(int d)
    {
    	
    }
    
    void date::setYear(int y)
    {
    	
    }
    
    int date::getMonth()
    {
    	return month;
    }
    
    int date::getYear()
    {
    	return year;
    }
    
    int date::getDay()
    {
    	return day;
    }
    
    void date::printDate()
    {
    	
    }
    
    void date::printDateX()
    {
    	cout << mnames[month-1] << " " << day << ", "<< year;	
    }
    
    
    
    ostream& operator<<(ostream &cs, const date &d)
    {
    	cs<<d.month<<"/"<<d.day<<"/"<<d.year<<" ";
    	return cs;
    }
    
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    If static char *mnames[]; relates to static char *mnames[]= { "Jan",..., then the problem is that you need to declare the latter as date::mnames, not just mnames.
     
  3. thekevin07

    thekevin07 New Member

    Joined:
    Sep 13, 2008
    Messages:
    29
    Likes Received:
    0
    Trophy Points:
    0
    i changed it to

    Code:
    static char *date::mnames[]= { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec" };
    
    now it gives the err

    Code:
    error C2720: 'date::mnames' : 'static ' storage-class specifier illegal on members
    i tried removing the static keyword and it gives a linker error

    Code:
    1>employee.obj : error LNK2019: unresolved external symbol "public: __thiscall date::date(class date &)" (??0date@@QAE@AAV0@@Z) referenced in function "public: class date __thiscall Employee::getHireDate(void)" (?getHireDate@Employee@@QAE?AVdate@@XZ)
    Employee is another class I have

    employee.h
    Code:
    #pragma once
    #include <string>
    #include "date.h"
    
    using namespace std;
    
    class Employee
    {
    	private:
    		int division;
    		int dept;
    		string name;
    		const int empNo;
    		date hireDate;
    		date promotionDate;
    		string classification;
    		float salary, currentHours;
    		static int size;
    
    	public:
    		//a default constructor
    		Employee(void);
    		//  a constructor to initialize new-ly created structs.
    		//todo: date class
    		Employee(int,int,string,date,date,string,float,float);
    		//destructor
    		~Employee(void);
    
    		int getSize();
    
    		int getDivision();
    		int getDept();
    		string getName();
    		date getHireDate();
    		date getPromotionDate();
    		string getClassification();
    		bool getExempt();
    		float getSalary();
    		float getCurrentHours();
    		const int getEmpNo();
    
    		void setDivision(int d);
    		void setDept(int de);
    		void setName(string n);
    		void setHireDate(date hd);
    		void setPromotionDate(date pd);
    		void setClassification(string c);
    		void setExempt(bool e);
    		void setSalary(float s);
    		void setCurrentHours(float ch);
    
    		virtual void printEmployee();
    		virtual float pay();
    };
    
    employee.cpp
    Code:
    #include "employee.h"
    #include <iostream>
    
    //keep track of how many employees we have
    int Employee::size=0;
    
    Employee::Employee(void): empNo(size++)
    {
    	currentHours=0.0;
    }
    
    Employee::Employee(int div, int dep, string n, date hire, date prom, string cls, float salry, float curHr=0):empNo(size++)
    {
    	division=div;
    	dept=dep;
    	name=n;
    	hireDate=hire;
    	promotionDate=prom;
    	classification=cls;
    	salary=salry;
    	currentHours=curHr;
    }
    
    
    int Employee::getSize()
    {
    	return size;
    }
    
    int Employee::getDivision()
    {
    	return division;
    }
    
    int Employee::getDept()
    {
    	return dept;
    }
    
    string Employee::getName()
    {
    	return name;
    }
    
    date Employee::getHireDate()
    {
    	return hireDate;
    }
    
    date Employee::getPromotionDate()
    {
    	return promotionDate;
    }
    
    string Employee::getClassification()
    {
    	return classification;
    }
    
    float Employee::getSalary()
    {
    	return salary;
    }
    
    float Employee::getCurrentHours()
    {
    	return currentHours;
    }
    
    const int Employee::getEmpNo()
    {
    	return empNo;
    }
    
    void Employee::setDivision(int d)
    {
    	division=d;
    }
    
    void Employee::setDept(int de)
    {
    	dept=de;
    }
    
    void Employee::setName(string n)
    {
    	name=n;
    }
    
    void Employee::setHireDate(date hd)
    {
    	hireDate=hd;
    }
    
    void Employee::setPromotionDate(date pd)
    {
    	promotionDate=pd;
    }
    
    void Employee::setClassification(string c)
    {
    	classification=c;
    }
    
    void Employee::setSalary(float s)
    {
    	salary=s;
    }
    
    void Employee::setCurrentHours(float ch)
    {
    	currentHours=ch;
    }
    
    
    void Employee::printEmployee()
    {
    	cout<<"Name: " << name.c_str()
    		<< " Div: " << division
    		<< ""
    		<< ""
    		<< ""
    		<< ""
    		<< ""
    		<< " Current hours: ";
    
    }
    
    float Employee::pay()
    {
    	//return getSalary(); geoff
    	return (float) salary; //teacher
    }
    
     
  4. oogabooga

    oogabooga New Member

    Joined:
    Jan 9, 2008
    Messages:
    115
    Likes Received:
    11
    Trophy Points:
    0
    1. removing "static" (on the static member's definition in date.cpp) was the correct thing to do.

    2. This is a completely different error. You forgot to implement "data::date(date &)" in data.cpp (although it is in date.h).
     
  5. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    Yep, sorry about that, oogabooga's right, static isn't needed. One day I'll learn to compile it first...

    What errors do you get for the employee class?
     
  6. thekevin07

    thekevin07 New Member

    Joined:
    Sep 13, 2008
    Messages:
    29
    Likes Received:
    0
    Trophy Points:
    0

    What do i put in the body for date(date &) i have no clue what to put here.
     
  7. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    Normally you would copy the members across from the parameter; this is a copy constructor.
    Code:
    date::date(date &d)
    {
    month=d.month;
    day=d.day;
    year=d.year;
    }
    
    The default copy constructor given to you by the compiler just directly copies the bits across, so the above isn't strictly necessary, but it's good practice to define one anyway as reliance on default behaviours can be a bad idea (defaults have a habit of changing unexpectedly). If your copy constructor does something smarter than just copy the bits though, then you would need one (it might not make sense to copy the data, say if one of the members was a pointer it might need to point to a new thing, not to the same thing as would be the case if you just copied the bits across).
     
    Last edited: Oct 7, 2008
  8. thekevin07

    thekevin07 New Member

    Joined:
    Sep 13, 2008
    Messages:
    29
    Likes Received:
    0
    Trophy Points:
    0
    Thank you, it compiles :)
     

Share This Page