CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Mar 2010
    Posts
    3

    Node containing class object (rather than int)

    I'm making a red black tree (RedBlack class) whose nodes will contain customers (customer class) rather than the generic int data. Unfortunately, I can't seem to get VS 2008 Express recognize that data is of type customer. I get all sorts of redefinition errors, and I've tried pragma once and include guards to no avail.

    Code:
    //HEADER for customer class//
    #include <string>
    using namespace std;
    class customer
    {
    public:
    	customer();
    	customer(string last, char first, int balance);
    	void set_account(int balance);
    	string get_name();
    	char get_initial();
    	int get_account();
    	~customer(void);
    private:
    	string name;//customer's last name
    	char initial;//customer's first initial
    	int account;//balance owed by customer
    };
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //CPP FILE for customer class
    #include "StdAfx.h"
    #include "customer.h"
    
    customer::customer(){
    }
    customer::customer(string last, char first, int balance)
    {
    	name = last;
    	initial = first;
    	account = balance;
    }
    void customer::set_account(int balance){
    	account = balance;
    }
    string customer::get_name(){
    	return name;	
    }
    char customer::get_initial(){
    	return initial;
    }
    int customer::get_account(){
    	return account;
    }
    customer::~customer(void)
    {
    }
    Code:
    //HEADER
    #pragma once
    //#ifndef CUSTOMER_H
    //#define CUSTOMER_H
    #include "customer.h"
    
    class RedBlack
    {
    private:
    	struct node {
    		bool red; //True if red, False if black
    		int data; //customer data
    		struct node *next[2]; //pointer to an array where index 0 is left and index 1 is right
    	};
    	node *root;
    	customer data;
    	struct tree{
    	struct node *root;//pointer to the root
    	};
    public:
    	RedBlack();
    	bool isRed(struct node *root);
    	~RedBlack(void);
    
    //#endif
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //CPP
    #include "StdAfx.h"
    //#ifndef CUSTOMER_HPP
    //#define CUSTOMER_HPP
    
    #include "RedBlack.h"
    
    RedBlack::RedBlack()
    {
    	root = NULL;
    }
    bool RedBlack::isRed(struct node *root){
    	if (root != NULL && root->red == true)
    		return true;
    }
    RedBlack::~RedBlack(void)
    {
    }
    //#endif
    };
    Any help would be much appreciated

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

    Re: Node containing class object (rather than int)

    You should:
    • Use header inclusion guards for headers, including the one with the customer class definition.
    • Never use using directives (e.g., using namespace std) or using declarations in a header except within some restricted scope.
    • Get rid of the data member variable in the RedBlack class, and instead change the type of RedBlack::node's data member variable to be customer.


    By the way, is there any reason why you do not use std::set or std::map instead?
    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

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Node containing class object (rather than int)

    Quote Originally Posted by paraboloid View Post
    I'm making a red black tree (RedBlack class) whose nodes will contain customers (customer class) rather than the generic int data.
    In addition to what laserlight says, why didn't you use a templated RedBlack class? Then it doesn't matter what the type is, and you write the code only once.

    Your header file should look like this (get rid of customer.h in the includes. The RedBlack tree doesn't care about what type you use).
    Code:
    #ifndef REDBLACK_H
    #define REDBLACK_H
    
    template <typename T>
    class RedBlack
    {
    private:
    	struct node {
    		bool red; //True if red, False if black
    		T data; 
    		struct node *next[2]; //pointer to an array where index 0 is left and index 1 is right
    	};
    	node *root;
    	T data;
    	struct tree{
    	struct node *root;//pointer to the root
    	};
    public:
    	RedBlack() : root(0) { }
    	bool isRed(struct node *root) const
            {
      	   return (root && root->red == true);
            }
    };
    #endif
    Now in your main program, you do this:
    Code:
    #include "redblack.h"
    #include "customer.h"
    
    int main()
    {
       RedBlack<customer> CustomerTree;
    // if you wanted an integer
       RedBlack<int>  IntTree;
    }
    This is what C++ templates are about. If I wanted a red-black tree of doubles, instead of changing the red-black tree code over and over again, just because the types change, I just declare a RedBlack tree of that type.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Mar 2010
    Posts
    3

    Re: Node containing class object (rather than int)

    Quote Originally Posted by laserlight View Post
    You should:
    • Use header inclusion guards for headers, including the one with the customer class definition.
    • Never use using directives (e.g., using namespace std) or using declarations in a header except within some restricted scope.
    • Get rid of the data member variable in the RedBlack class, and instead change the type of RedBlack::node's data member variable to be customer.


    By the way, is there any reason why you do not use std::set or std::map instead?
    I've been learning c++ for two months, so if what I'm doing seems off, I don't know any better.
    I learned about inclusion guards this morning in a forum, so I didn't know they were recommended for all headers. The compiler told me I needed using namespace std in order to use <string>. And I have never seen std::set or std::map hence my not using them.

    And I wasn't aware that I could omit the cpp file and just have all my code in the header...

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Node containing class object (rather than int)

    Quote Originally Posted by paraboloid View Post
    The compiler told me I needed using namespace std in order to use <string>.
    The <string> header, and #includes in general, have nothing to do with namespaces. The std::string *class* does live in the std namespace, of course, but you can always just refer to it as "std::string" without a using statement. This is the preferred approach for header files.

    For source files, a using statement is fine, and it saves you typing 5 extra characters each time you want a string. The issue with headers is that any using statement is a header file is propagated to source files which include it, basically defeating the purpose of namespaces to begin with.

    And I have never seen std::set or std::map hence my not using them.
    http://www.cplusplus.com/reference/stl/

    And I wasn't aware that I could omit the cpp file and just have all my code in the header...
    Careful----in general, this is a bad idea. In many cases it won't even compile, and even if it does, putting more code than necessary into a header may slow down your compiles.

    However, when working with templates you are forced to put more into a header than you normally would. Don't worry about that for now, though, one thing at a time.

  6. #6
    Join Date
    Mar 2010
    Posts
    3

    Re: Node containing class object (rather than int)

    I'm going to assume we never learned about STL containers because that's what we've been coding by scratch.

    Quote Originally Posted by Paul McKenzie View Post
    Code:
    #ifndef REDBLACK_H
    #define REDBLACK_H
    
    template <typename T>
    class RedBlack
    {
    private:
    	struct node {
    		bool red; //True if red, False if black
    		T data; 
    		struct node *next[2]; //pointer to an array where index 0 is left and index 1 is right
    	};
    	node *root;
    	T data;
    	struct tree{
    	struct node *root;//pointer to the root
    	};
    public:
    	RedBlack() : root(0) { }
    	bool isRed(struct node *root) const
            {
      	   return (root && root->red == true);
            }
    };
    #endif
    Just wondering how I make this work if I used a cpp file too. The template stuff seems to require something extra, and I can't see anything online that deals with this issue.

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Node containing class object (rather than int)

    One approach is to put the code in a .inl file. The extension doesn't really matter, it's just a way of making it not be a cpp file, because it should not be built as a separate translation unit. Then, you could put

    #include "RedBlack.inl" at the end of RedBlack.h.

Tags for this Thread

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