CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    May 2009
    Posts
    19

    Class Definition header-source problems

    Hi all.

    I'm trying to define a class in a header file, and implement it separately. However, my compiler is telling me that the class is being redefined. I recognize what the error is telling me, but I'm not sure what to do to fix it.

    the header file:
    Code:
    #include <string>
    using namespace std;
    
    #ifndef VENDORFUNCS_HPP_
    #define VENDORFUNCS_HPP_
    
    template<class t> void copyArray(t* from, t** dest, unsigned int length, bool assignval=true);
    
    class Vendor{//<<<<<ERROR HERE>>>>>
    
    public: Vendor(string vendorname, string* productnames, int slength, double* prodprices, int dlength);
    
    	bool purchase(string name, double withmoney);
    	string getName();
    	double getPrice(string product);
    	string* valuesUnder(double d, int &arrlength);
    };
    
    #endif
    and the source file:
    Code:
    #include <string>
    #include "VendorFuncs.hpp"
    
    template <class t> void copyArray(t* from, t** dest, unsigned int length, bool assignval){
    	if(assignval){
    		*dest = new t[length];
    	}
    	for(unsigned int i=0; i<length; i++){
    		(*dest)[i] = from[i];
    	}
    
    }
    
    class Vendor{//<<<<<<ERROR HERE>>>>>>
    	string name;
    	string* products;
    	double* prices;
    	int productNumber;
    	int findProduct(String name){
    		for(int i=0; i<productNumber; i++){
    			if(products[i]==name) return i;
    		}
    	}
    
    public:
    	Vendor(string vendorname, string* productnames, double* prodprices, int numProducts){
    		name=vendorname;
    		copyArray(productnames, &products, slength);
    		copyArray(prodprices, &prices, dlength);
    		productNumber=numProducts;
    	}
    
    	bool purchase(string pname, double money){
    		int indx = findProduct(pname);
    		if(prices[indx]>money) return false;
    		else return true;
    	}
    
    	string getname(){
    		return name;	
    	}
    	double getPrice(String pname){
    		return prices[findProduct(pname)];
    	}
    	string* valuesUnder(double amt, int &lenindic){
    		lenindic=0;
    		string* arr = new string[productNumber];
    		for(int i=0; i<productNumbet; i++){
    			if(prices[i]<=amt){
    				arr[lenindic]=products[i];
    				lenindic+=1;			
    			}
    		}
    		return arr;
    	}
    };
    I know what I could do if I was not using private variables in the class, but I'm hoping there is some way to do this without taking them out.

  2. #2
    Join Date
    Feb 2009
    Posts
    326

    Re: Class Definition header-source problems

    Class can be declared only once.

    You have declared it in your header file.

    In the implementation file, you need to define (not declare) it.

    1) Use scope resolution operator :: to define functions of the class.
    2) Also noticed that the member variables of the class Vendor were not declared in the header file.

    It might help if you read from a book so that the fundamentals are clear.

    I have just done it for one function getName()

    header file
    Code:
    #include <string>
    using namespace std;
    
    #ifndef VENDORFUNCS_HPP_
    #define VENDORFUNCS_HPP_
    
    template<class t> void copyArray(t* from, t** dest, unsigned int length, bool assignval=true);
    
    class Vendor
    {//<<<<<ERROR HERE>>>>>
            
        public: 
            Vendor(string vendorname, string* productnames, int slength, double* prodprices, int dlength);  
            bool purchase(string name, double withmoney);
            string getName();
            double getPrice(string product);
            string* valuesUnder(double d, int &arrlength);
            
        private:
            string name;
    };

    implementation file:
    Code:
    #include <string>
    #include "VendorFuncs.hpp"
    
    template <class t>  
    void copyArray(t* from, t** dest, unsigned int length, bool assignval)
    {
        if(assignval){
            *dest = new t[length];
        }   
        for(unsigned int i=0; i<length; i++){
            (*dest)[i] = from[i];
        }   
        
    }
    
    
    string Vendor :: getName()
    {
        return name;
    }
    Last edited by Muthuveerappan; July 9th, 2009 at 09:55 PM.

  3. #3
    Join Date
    Aug 2007
    Posts
    858

    Re: Class Definition header-source problems

    You are redefining the class. Variables, whatever their visibility, must be given in the class definition.

    Code:
    // MyClass.h
    
    class MyClass
    {
    public:
      MyClass( );
    
      void doStuffToVar( );
    
    private:
      int m_var;
    };
    
    // MyClass.cpp
    #include "MyClass.h"
    
    MyClass::MyClass( )
    : m_var(0)
    {
    }
    
    void MyClass::doStuffToVar( )
    {
      // stuff
    }
    If you are wanting to completely hide the implementation details of your class, look at the pimpl idiom.

    Edit:
    Class can be declared only once.

    You have declared it in your header file.

    In the implementation file, you need to define (not declare) it.
    Slight nitpick on terminology - in the header file you declare and define a class. That class definition is all the info the compiler needs to actually use the class. However the member function of the class are only declared in the header (unless they are inlined), and they must still be defined somewhere so that the linker will be able to access them. Basically, you have to distinguish between class declaration/definition and [class member] function declaration/definition.
    Last edited by Speedo; July 9th, 2009 at 10:03 PM.

  4. #4
    Join Date
    May 2009
    Posts
    19

    Re: Class Definition header-source problems

    Ah ok... I had not thought that the private variables/functions would be defined in the header file. Apparently I was wrong.

    Thanks for all your help, works fine now!

  5. #5
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: Class Definition header-source problems

    and NEVER use "using" in a header file as this pollutes the name lookup.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Class Definition header-source problems

    Quote Originally Posted by Richard.J
    and NEVER use "using" in a header file as this pollutes the name lookup.
    Or rather, never use using declarations or using directives at namespace scope in header files.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    Join Date
    Feb 2009
    Posts
    326

    Re: Class Definition header-source problems

    I have some doubts regarding Richard's and Laserlight's comments.

    Richard
    ----------
    I understand that using directive (such as using namespace std) instructs the compiler to recognize all the members in that namespace which is undesirable and can cause problems.

    Sometimes in the header file, I have a function that has parameter of the type std :: string.
    So in those cases I use using declarations in the header file (such as using std :: string).

    Laserlight
    ------------
    I am too sure I understood Laserlight's comments. Laserlight, Are you stating that if at all the using declarations are to be used, you must use it within the scope of namespace that requires it and not globally ?

    Is that what you meant, or have I got it all wrong ?

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Class Definition header-source problems

    Quote Originally Posted by Muthuveerappan
    Sometimes in the header file, I have a function that has parameter of the type std :: string.
    So in those cases I use using declarations in the header file (such as using std :: string).
    So, what happens if I include your header and also include another header from another library with a class named string? Or maybe I happen to be writing a program dealing with guitars... it would be rather inconvenient if I have to fully qualify string whenever I mean a guitar string, even though my usage of guitar::string far exceeds that of std::string, wouldn't it?

    Quote Originally Posted by Muthuveerappan
    I am too sure I understood Laserlight's comments. Laserlight, Are you stating that if at all the using declarations are to be used, you must use it within the scope of namespace that requires it and not globally ?
    No, I am stating that if you do use them in a header file, it should be within the scope of a function or a class.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Mar 2008
    Posts
    38

    Re: Class Definition header-source problems

    I am lost. Templates are implemented in the .h file, not .cpp.

  10. #10
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Class Definition header-source problems

    Quote Originally Posted by sdcode
    I am lost. Templates are implemented in the .h file, not .cpp.
    Singing Boyo might not have actually tried to use the function template yet.

    EDIT:
    Ah yes, and I recall that there are workarounds for implementing function templates in source files other than the "include source file in header" trick: How can I avoid linker errors with my template functions?
    Last edited by laserlight; July 10th, 2009 at 02:06 PM.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  11. #11
    Join Date
    Feb 2009
    Posts
    326

    Re: Class Definition header-source problems

    I have explained below my understand, pls correct me if I am wrong:

    The #include must continue to be in global scope.

    It is the using declaration which need to be is in the smallest scope required.

    Thank you so much Laserlight for that explanation.

    I didn't even know that using declaration could be specified in a class / function.

    Now I guess the semi-colon at the end of the using declaration makes sense.

  12. #12
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Class Definition header-source problems

    Quote Originally Posted by Muthuveerappan
    The #include must continue to be in global scope.
    It defines a macro, and macros do not obey the rules of scope.

    Quote Originally Posted by Muthuveerappan
    It is the using declaration which need to be is in the smallest scope required.
    At least in a header file, if it is used at all. For a source file, I believe opinions are more varied.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  13. #13
    Join Date
    Feb 2009
    Posts
    326

    Re: Class Definition header-source problems

    Thank you so much for that explanation, learned something new

    I guess in case of templates, the implementation file is as significant as the header file (both are required to instantiate), so I guess it best to follow your advice on the implementation file as well.
    Last edited by Muthuveerappan; July 11th, 2009 at 01:20 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured