C++ Set Class

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
I am writing a program for a class. Basically it has to do with mathematical sets. My professor gave us the following useSets.cpp and we were to write the MySets.cpp and MySets.h files. The only error I get now when I compile MySets.cpp is " [Linker error] undefined reference to `WinMain@16' ". When I compile useSets.cpp I get a crap load of errors and have no idea how to go about fixing them. If anyone can take a look at this, it would be greatly appreciated.

// FILE: useSets.cpp
#include "MySet.H"
#include <iostream> // used for cin, cout, etc
#include <cstdlib> // used for EXIT_SUCCESS
#include <ctime> // used to seed the random number generator
using namespace std;

int main() {
srand((unsigned)time(0)); // Seed the random number generator
MySet PossibleNumbers("Possible");
for(int i = 1; i <= 60; i++)
PossibleNumbers += i;
MySet Winners("WIN");
// RANDOMLY PICK 6 WINNING NUMBERS
while(Winners.cardinality() < 6) {
int randNum = 1 + (int)(60.0 * (rand()/(RAND_MAX + 1.0)));
if(!Winners.inSet(randNum))
Winners += randNum;
}

// TOM BUYS 10 LOTTERY TICKETS USING QUICK PICK
MySet *Tom;
Tom = new MySet[10];
for(int i = 0; i < 10; i++) {
Tom.setLabel("TOM");
while(Tom.cardinality() < 6) {
int randNum = 1 + (int)(60.0 * (rand()/(RAND_MAX + 1.0)));
if(!Tom.inSet(randNum))
Tom += randNum;
}
}

// JIM BUYS 1 LOTTERY TICKET USING HIS FAVORITE NUMBERS
MySet Jim("JIM");
Jim += 2;
Jim += 3;
Jim += 15;
Jim += 19;
Jim += 29;
Jim += 35;
cout << PossibleNumbers << endl;

// PRINT OUT THE WINNING NUMBERS
cout << Winners << endl;
for(int i = 0; i < 10; i++) {
cout << Tom << endl;
// PRINT NUMBERS TOM GOT RIGHT -- INTERSECTION WITH WINNERS
cout << " " << Tom * Winners << endl;
}
cout << Jim << endl;

// PRINT NUMBERS JIM GOT RIGHT
cout << " " << Jim * Winners << endl;
MySet A("TomsTotals");
for(int i = 0; i < 10; i++)
A += Tom;
cout << "Here are all the numbers Tom picked: " << endl;
cout << A << endl;
cout << "Here are the numbers Jim and Tom had in common " << endl;
cout << (A * Jim) << endl;
cout << "Here are the numbers Tom had that Jim did not " << endl;
cout << (A - Jim) << endl;
cout << "Here are the numbers Jim had that Tom did not " << endl;
cout << (Jim - A) << endl;
MySet Picked("PICKED"); // All of the numbers that were picked
Picked += Jim;
Picked += A;
MySet NotPicked("NOTPICKED"); // possible numbers not picked
NotPicked += PossibleNumbers - Picked;
cout << Picked << endl;
cout << NotPicked << endl;
return EXIT_SUCCESS;
}

If anyone wants the .cpp and .h files hosted somewhere, I can find a place to do that.
 
Last edited:

05 Roush

Roushcharged
Established Member
Joined
Aug 7, 2003
Messages
16,685
Location
Front Range
The problem is you should be writing it in C# instead. :p

Seriously though, it sounds like you created the project as a Windows Application, not a Console Application. Or possibly no project at all.

Can you verify which one you created and if you're using Visual Studio?
 

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
Ha, then Data Structures in C++ wouldn't be an appropriate name for the class. I didn't create it as a project at all, I usually don't and I usually don't have any problems. I am currently using bloodshed dev-c++. I do have access to Visual Studio though, should I use it? And should I figure out how to turn this into a project instead?

EDIT: I put it together in a project and made sure it was a console application. It did fix my error in MySet.cpp but I am still getting errors like "48 C:\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::eek:perator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&)(&std::cout)), ((const char*)" ")) << operator*(MySet&, MySet&)(((MySet&)(&Winners)))' " when I compile useSets.cpp
 
Last edited:

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp In function `int main()':
48 C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::eek:perator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&)(&std::cout)), ((const char*)" ")) << operator*(MySet&, MySet&)(((MySet&)(&Winners)))'

53 C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::eek:perator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&)(&std::cout)), ((const char*)" ")) << operator*(MySet&, MySet&)(((MySet&)(&Winners)))'

60 C:\Documents and Settings\JMy Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::cout << operator*(MySet&, MySet&)(((MySet&)(&Jim)))'

62 C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::cout << operator-(MySet&, MySet&)(((MySet&)(&Jim)))'

64 C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::cout << operator-(MySet&, MySet&)(((MySet&)(&A)))'

69 C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator+=' in 'NotPicked += operator-(MySet&, MySet&)(((MySet&)(&Picked)))'

C:\Dev-Cpp\Makefile.win [Build Error] ["../Documents and Settings/Jason Raap/My Documents/CECS 302/Programming/HW1/useSets.o"] Error 1



There are about 10 notes that the compiler gives me with each one of these, but I can only copy one line at a time. Let me know if you want those also.
 

4VFreak

Beyaaahhhh!!!!!
Established Member
Joined
Jan 26, 2006
Messages
440
Location
Cincinnati, OH
It looks like the output operator '<<' and the '+=' aren't overloaded to handle the MySets class. You should check to make sure that you overloaded these operators in your MySets class that you wrote. For the '+=' you may only need to overload the '+' operator to handle your new class. It looks like you also use the '*' operator with your MySets class, that may need to be overloaded as well if it was not already.

Honestly though, I haven't dealt with straight C/C++ in a while and when I did it was on a Solaris Sparcstation with an Emacs editor. I have never written or compiled straight C++ in Windows. Also, if you open your straight C++ project in Visual Studio as a Visual C++ project, that may cause some issues to pop up. Like 05Roush said, C# and COM+ owns.
 
Last edited:

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
Wow, I feel really dumb. I just realized that I pasted the same file 3 times. Here are the other 2:

// FILE: MySet.cpp
#include <iostream>
#include "MySet.h"
using namespace std;
//Implementations

// ****************
// Constructors/Destructor
// ****************

// Default constructor
MySet::MySet() {
Container = new element_type[MAX_SET_SIZE];
maxSetSize = MAX_SET_SIZE;
setSize = 0;
}

// Constructor with label
MySet::MySet(string label) {
Container = new element_type[MAX_SET_SIZE];
maxSetSize = MAX_SET_SIZE;
setName = label;
setSize = 0;
}

// Constructor with label and max size
MySet::MySet(string label, int maxSize) {
Container = new element_type[maxSize];
maxSetSize = maxSize;
setName = label;
setSize = 0;
}

// Constructor with max size
MySet::MySet(int maxSize) {
Container = new element_type[maxSize];
maxSetSize = maxSize;
setSize = 0;
}

// Automatic Copy Constructor
MySet::MySet(const MySet &secondSet) {
Container = new element_type[secondSet.maxSetSize];
maxSetSize = secondSet.maxSetSize;
setName = secondSet.setName;
setSize = secondSet.setSize;
for(int i = 0; i < setSize; i++) {
Container = secondSet.Container;
}
}

// Destructor
MySet::~MySet() {
delete [] Container;
}

// ****************
// Member Functions
// ****************

// Returns the set size
int MySet::cardinality() {
return(setSize);
}

// Returns true if element is in the set; false otherwise
bool MySet::inSet(element_type element) {
for(int i = 0; i < setSize; i++) {
if(getElement(i) == element) {
return(true);
}
}
return(false);
}

// Returns true if set is full
bool MySet::isFull() {
if(setSize == maxSetSize) {
return(true);
}
return(false);
}

// Returns element at position index
element_type MySet::getElement(int index) {
return(Container[index]);
}

// Sets the name of the set
void MySet::setLabel(string label) {
setName = label;
}

void MySet::deleteElement(int index) {
for(int i = index; i < setSize; i++) {
Container = Container[i+1];
}
}

// ****************
// Overloaded operators as friend functions
// ****************

// Add contents of set B
void MySet::eek:perator += (MySet &B) {
for(int i = 0; i < B.setSize; i++) {
if(!inSet(B.Container)) {
Container[setSize] = B.Container;
setSize++;
}
}
}

// Add element to set
bool MySet::eek:perator += (element_type element) {
if(!isFull()) {
Container[setSize] = element;
setSize++;
return(true);
}
return(false);
}

// Subtract contents of second set
void MySet::eek:perator -= (MySet &B) {
for(int i = 0; i < setSize; i++) {
for(int j = 0; j < B.setSize; j++) {
if(B.getElement(j) == getElement(i)) {
deleteElement(i);
}
}
}
}

// Subtract single element from set
bool MySet::eek:perator -= (element_type element) {
for(int i = 0; i < setSize; i++) {
if(getElement(i) == element) {
deleteElement(i);
return(true);
}
}
return(false);
}
// assignment operator
void MySet::eek:perator = (MySet &secondSet) {
if(this == &secondSet)
return;
if(maxSetSize != secondSet.maxSetSize) {
element_type *newContainer;
newContainer = new element_type[secondSet.maxSetSize];
delete [] Container;
Container = newContainer;
maxSetSize = secondSet.maxSetSize;
}
setSize = secondSet.setSize;
for(int i = 0; i < setSize; i++) {
Container = secondSet.Container;
}
setName = secondSet.setName;
}


// ****************
// OVERLOAD FRIEND OPERATORS FOR UNION (+), INTERSECTION (*)
// DIFFERENCE (-) and OUTPUT (<<) AS WELL
// ****************

// Union
MySet operator + (MySet &A, MySet &B) {
MySet Union;
for(int i = 0; i < A.setSize; i++) {
Union.Container = A.Container;
Union.setSize++;
}
for(int j = 0; j < B.setSize; j++) {
for(int k = 0; k < A.setSize; k++) {
if(A.getElement(k) != B.getElement(j)) {
Union.Container[Union.setSize] = A.getElement(k);
Union.setSize++;
}
}
}
return(Union);
}

// Intersection
MySet operator * (MySet &A, MySet &B) {
MySet Intersection;
for(int i = 0; i < A.setSize; i++) {
for(int j = 0; j < B.setSize; j++) {
if(A.getElement(i) == B.getElement(j)) {
Intersection.Container[Intersection.setSize] = A.getElement(i);
Intersection.setSize++;
}
}
}
}

// Difference
MySet operator - (MySet &A, MySet &B) {
MySet Difference;
for(int i = 0; i < A.setSize; i++) {
for(int j = 0; j < B.setSize; j++) {
if(A.getElement(i) != B.getElement(j)) {
Difference.Container[Difference.setSize] = A.getElement(i);
Difference.setSize++;
}
}
}
}

// Output
ostream &operator << (ostream &os, MySet &A) {
os << A.setName << " = {";
for (int i = 0; i < A.setSize; i++) {
if(i == 1 - A.setSize) {
os << A.getElement(i) << "}" << endl;
}
else {
os << A.getElement(i) << ", ";
}
}
return(os);
}



// FILE: MySet.h
#ifndef MYSET_H
#define MYSET_H
#include <cstdlib>
#include <iostream>
#include <string>
#include <cassert>
using namespace std;

#define MAX_SET_SIZE 100 // Default maximum set size

#define element_type int// DEFINE element_type

class MySet {
public:
// FIRST, CONSTRUCTOR AND DESTRUCTOR PROTOTYPES
MySet();
MySet(string label);
MySet(string label, int maxSize);
MySet(int maxSize);
MySet(const MySet &secondSet); // automatic copy constructor
~MySet(); // Use clearcontainer for an array

// THEN PUBLIC MEMBER FUNCTIONS
int cardinality(); // Returns the set size
bool inSet(element_type element); // returns true if element is in the set; false otherwise
bool isFull(); // Returns true if set is full
element_type getElement(int index); // Returns element at position index
void setLabel(string label); // sets the name of the set
void deleteElement(int index);

// OVERLOADED OPERATORS AS MEMBER FUNCTIONS -, += (one for
// adding contents of a second set; one for adding single
// element) -=, =
void operator = (MySet &secondSet); // Assignment operator
void operator += (MySet &B); // Add set B to calling set
bool operator += (element_type element); // Add element to calling set
void operator -= (MySet &B); // Substract set B from calling set
bool operator -= (element_type element); // Subtract element from calling set

// OVERLOAD FRIEND OPERATORS FOR UNION (+), INTERSECTION (*)
// DIFFERENCE (-) and OUTPUT (<<) AS WELL
friend MySet operator + (MySet &A, MySet &B);
friend MySet operator * (MySet &A, MySet &B);
friend MySet operator - (MySet &A, MySet &B);
friend ostream &operator << (ostream &os, MySet &A);

private:
// PRIVATE DATA MEMBERS AND FUNCTIONS CAN ONLY BE ACCESSED
// WITHIN THE CLASS AND FRIENDS OF THE CLASS
element_type *Container;
int setSize; // number of elements for the set
string setName; // label for the set
int maxSetSize; // maximum number of elements for the set


};
#endif
 

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
4VFreak said:
It looks like the output operator '<<' and the '+=' aren't overloaded to handle the MySets class. You should check to make sure that you overloaded these operators in your MySets class that you wrote. For the '+=' you may only need to overload the '+' operator to handle your new class. It looks like you also use the '*' operator with your MySets class, that may need to be overloaded as well if it was not already.

Honestly though, I haven't dealt with straight C/C++ in a while and when I did it was on a Solaris Sparcstation with an Emacs editor. I have never written or compiled straight C++ in Windows. Also, if you open your straight C++ project in Visual Studio as a Visual C++ project, that may cause some issues to pop up. Like 05Roush said, C# and COM+ owns.

I am pretty new to overloaded operators, but I am pretty sure that I have all of them overloaded. Thanks for your help guys.
 

JasonSnake

Active Member
Established Member
Joined
Oct 11, 2005
Messages
6,739
Location
USA
wish I could help but I'm still at teh beginning of my first c++ course.

Maybe you need to include the <cmath> library? Just a guess...
 

4VFreak

Beyaaahhhh!!!!!
Established Member
Joined
Jan 26, 2006
Messages
440
Location
Cincinnati, OH
Yeah, your overloaded operators seem ok to me.

Maybe you should compile with a makefile instead of using a Visual Studio project. A makefile might be a way to make sure that things are compiling in the right order.
 

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
4VFreak said:
Yeah, your overloaded operators seem ok to me.

Maybe you should compile with a makefile instead of using a Visual Studio project. A makefile might be a way to make sure that things are compiling in the right order.

Can you tell me how to do that? Never heard of a makefile before. Originally I was not using a project though and it still wasn't working.
 

4VFreak

Beyaaahhhh!!!!!
Established Member
Joined
Jan 26, 2006
Messages
440
Location
Cincinnati, OH
theraapster said:
Can you tell me how to do that? Never heard of a makefile before. Originally I was not using a project though and it still wasn't working.

Creating a makefile can depend on what compiler you are using. Google around on makefiles for your particular compiler. There probably is some information on setting one up for your situation. Let me know what compiler you are using and I will look around some too.

I am not promising anything on this, this is kind of a shot in the dark as to what the problem is. I would think that a Visual C++ Project would take care of compilation details for you, so it makes me think that the problem may be something else. I have also never used a makefile in Windows so I don't know what to expect from this. I'll look around as well and see if I can come up with anything else.
 
Last edited:

4VFreak

Beyaaahhhh!!!!!
Established Member
Joined
Jan 26, 2006
Messages
440
Location
Cincinnati, OH
Just spotted something. Your intersection '*' and difference '-' operators a don't have return() statements. These are probably making the compiler crap out on your MySet.cpp file and since the ostream '<<' operator is after those functions, it doesn't get compiled as well. Try adding the return(Intersection) and return(Difference) statements to their respective functions.
 

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
Good catch! However, that did not solve the problem. I do know about the makefile for linux, I just never put that together in windows. I am still getting this error: "49 C:\Documents and Settings\My Documents\CECS 302\Programming\HW1\useSets.cpp no match for 'operator<<' in 'std::eek:perator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&)(&std::cout)), ((const char*)" ")) << operator*(MySet&, MySet&)(((MySet&)(&Winners)))' " which has to do with this line:
cout << " " << Tom * Winners << endl;
 

4VFreak

Beyaaahhhh!!!!!
Established Member
Joined
Jan 26, 2006
Messages
440
Location
Cincinnati, OH
Is that the only error, or are all of the errors still occuring?

Try using the dereferencing operator '*' on the array of sets (Tom):

cout << " " << *Tom * Winners << endl;
 

theraapster

Member
Established Member
Joined
Apr 25, 2004
Messages
661
Location
NKY
No, that is not the only error, but most of them have to do with the overloaded operator <<. Most of them say " no match for 'operator<<' in 'std::cout << " and then whatever is calling it.

EDIT: The dereferencing operator didn't work.
 

JasonSnake

Active Member
Established Member
Joined
Oct 11, 2005
Messages
6,739
Location
USA
if you want to try another program, I downloaded www.Cygwin.com which emulated a terminal environment and uses xemacs . I have to use g++ command to compile with it.

There are 3 components you need to download. Let me know if you want to try it so I can find my sheet on what you're supposed to d/l.
 

Users who are viewing this thread



Top