could someone point out any existing Issues with this code so I can get some Idea of what I may have been learning the wrong way. |
Wow, that's pretty bad indeed. It's especially dismaying to see so much wrong about operator overloading in what claims to be teaching that topic.
Catfish already pointed out quite a few problems, here's one more point of view
using namespace std;
fine in a small source file, very bad in a header file. Here it's up there before a class definition which would be something to go into a header file if you wanted to extend this.. so don't
const int MaxSize = 100;
part of Set, belongs inside the class, not outside. And, as Catfish said, it's silly for it to be a signed int
int len; //number of members
would work best as std::size_t as well, of course.
char members[MaxSize]; //this array holds the set
This makes each Set object occupy entire MaxSize bytes, even if it's "empty" or populated just by a handful of items as in this example. This should be std::vector<char> (which would also remove the need for MaxSize and len), or, given that these are chars, std::string. With a
sorted vector
members
, it would even make it possible to turn this into an actually sensible example.
int find(char ch); // find an element
strange choice for a private member function, it has design problems (as already pointed out) - but even if you pretend that it is okay, it needs to be const.
Set() {len=0;}
This needs to be at least
Set() : len(0) {}
(or, for the fans of value-initialization
Set() : len() {}
). Of course, if
members
is a vector, it's not needed at all.
int getLength() {return len;}
needs to be const, if needed at all (is not used in this program)
void showset(); //display the set
needs to be const at least, but, more importantly, this should not be a class member function (although explaining interface design is not the topic here)
bool isMember(char ch); //check for membership
needs to be const (or possibly non-member)
1 2
|
Set operator +(char ch); // add an element
Set operator -(char ch); //remove an element
|
I actually did a double-take here. Binary operators are (almost) never implemented as member functions. Also, if you're defining a binary operator, you need to define its compound assignment counterpart (operator+= for operator+, operator-= for operator-) , and *those* are often made member functions (although they don't need to be in general, they need to be here).
1 2
|
Set operator +(Set ob2); // set union
Set operator -(Set ob2); // set difference
|
And (I think Catfish pointed it out too), this is needlessly taking the argument by value -- making an extra copy, and even if there's a chance for a move, since Set is using an array rather than a vector, it can't be optimized even then!
1 2
|
int i;
for(i=0;i<len;i++)
|
This isn't 1980s C, initialize the counter inside the loop, like in showset(). That is, if you want to use a loop at all - C++ has a std::find(), after all.
1 2
|
if(find(ch) != -1) return true;
return false;
|
A little redundant to evaluate a boolean expression and then return true if it is true, and the design is so questionable, but whatever, let's look at the operators.
1 2 3
|
Set newset;
[...]
newset =*this; // duplicate the existing set
|
what's the point of creating a Set if it's only given a value several lines (and possible return point) later? If you must do that, at least write
Set newset = *this;
(although it's bad for other reasons)
1 2
|
// see if element already exists
if(find(ch) == -1) { //if not found ,then add
|
Did he forget he just defined isMember?
1 2
|
cout<< "Set is full.\n";
return *this; //return existing set
|
operator+ shouldn't randomly print out messages to standard output and continue as if nothing happened, this calls for an exception (although if members were a regular, resizeable container, this wouldn't be a problem)
Now, how to rewrite those operator+'s using less awkward C++ (although it's still a bit painful because of the array involved)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
class Set {
[...]
Set& operator+=(char ch) {
if(len == MaxSize)
throw std::overflow_error("Set is full in operator+");
if(!isMember(ch))
members[len++] = ch;
return *this;
}
Set& operator+=(const Set& rhs) {
for(int i=0; i< rhs.len; ++i)
*this += rhs.members[i];
return *this;
}
};
// nonmember, one arg by value to call += on, other by ref
Set operator+(Set lhs, const Set& rhs)
{
return lhs += rhs;
}
Set operator+(Set lhs, char rhs)
{
return lhs += rhs;
}
Set operator+(char lhs, Set rhs) // so 'a' + set works too
{
return rhs += lhs;
}
|