-
March 30th, 2010, 01:08 PM
#1
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
-
March 30th, 2010, 01:14 PM
#2
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?
-
March 30th, 2010, 03:17 PM
#3
Re: Node containing class object (rather than int)
Originally Posted by paraboloid
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
-
March 30th, 2010, 04:41 PM
#4
Re: Node containing class object (rather than int)
Originally Posted by laserlight
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...
-
March 30th, 2010, 04:53 PM
#5
Re: Node containing class object (rather than int)
Originally Posted by paraboloid
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.
-
March 30th, 2010, 07:23 PM
#6
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.
Originally Posted by Paul McKenzie
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.
-
March 30th, 2010, 07:30 PM
#7
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|