Welcome! Log In Create A New Profile

Advanced

Is this the way to declare a class?

Posted by 36187844 
Announcements Last Post
Announcement SoC Curricula 09/30/2017 01:08PM
Announcement Demarcation or scoping of examinations and assessment 02/13/2017 07:59AM
Announcement School of Computing Short Learning Programmes 11/24/2014 08:37AM
Announcement Unisa contact information 07/28/2011 01:28PM
Is this the way to declare a class?
June 15, 2006 04:34PM
I'm having some trouble understanding class declerations in C++.

below is a template of how i see how classes are defined:

#ifndef HEADERFILENAME_H
#define HEADERFILENAME_H

//includes follow below
#include <string>

using namespace std; //is this always required?

class MyClass
{
public:
//all public declarations go here
//Default Constructor and overloaded constructors? like
MyClass(); //and
MyClass(string MyName);
protected:
//is this where i'll usually put my mutators and inspectors? like
string GetName() const; //is the const in the right place?
void SetName(string MyName);
private:
// it would seem that class variables go here and other facilitarors?
string MyName; //?
void DisplayName();
};

//does the class implementation follow here? or is this where ADTs come in

#endif

Although C++ and Java is similar, Java seems much easier grinning smiley
Re: Is this the way to declare a class?
June 16, 2006 09:13PM
I'm battling a bit with the C++ classes myself

my major development experience has been with COBOL and other such RPC languages
Also SQL server.

I have dabbled a bit with C# and seem to have a slight understanding of how classes work there.

this is all quite a paradigm shift for me.
Re: Is this the way to declare a class?
June 17, 2006 12:39AM
I've done java and learnt about classes there. its really simple cause the way you write them like is as easy as writing normal functions (default constructor, overloaded constructors etc.), none of this implementation rubbish in other files.

the cohoon & davidson handbook doesn't make it clear either... angry smiley

after starting this thread i reread parts of chapter 7 and 8 so now the only confusing bit is the auxilary stuff (the parameter>> stuff and the ostream stuff)

do you also have trouble with that?
avatar Re: Is this the way to declare a class?
June 17, 2006 04:56AM
-------------- Quoted code ----------------------------
 
#ifndef HEADERFILENAME_H
#define HEADERFILENAME_H
 
//includes follow below
#include <string>
 
using namespace std; //is this always required? NEVER put this in a header. Unfortunately it will take an essay to explain why. 
You'll have to prefix all the STL classes with "std::" to use them though 
class MyClass
{
   public:
      //all public declarations go here
      //Default Constructor and overloaded constructors? like
      MyClass(); //and
      MyClass(std::string MyName);
   protected:
      //is this where i'll usually put my mutators and inspectors? like
      std::string GetName() const; //is the const in the right place? Yes it is (see later)
      void SetName(std::string MyName);
   private:
       // it would seem that class variables go here and other facilitarors?
      std::string MyName; //?
      void DisplayName();                     
};

//does the class implementation follow here? or is this where ADTs come in hmm, this is a tautology
 
#endif
----------- End of Quoted code ---------------------------------------

First things first. You don't have to make your inspectors and mutators (or getters and setters) protected; you can put them anywhere. It all depends on what you want to allow access to. Public members are accessible by everything. Private memebers are only accessible by functions defined in MyClass. protected members are accessible by functions in MyClass and functions in any class that inherits from MyClass. If you want to do something like:
#include <iostream>
#include "HeaderFilename.h"
using namespace std;

void main()
  {
  MyClass intance;

  instance.SetName("Joe Soap"winking smiley;
  cout << instance.GetName() << endl;
  }
then you have to make both GetName() and SetName() public.

==================

When you used the keyword const at the end of GetName(), you were not referring to the return type, you were referring to the function itself - GetName is a constant function. There are very good reasons for doing this and why you should get into the habit of using them wherever you can.

When you define constants in your code, you essentially say that once it has been initialised, you will not be able to alter it's value. e.g.
const int ConstInt = 16;
You will not be allowed to change the value of ConstInt. Now, you can define ANY instance of a data type as a constant - and sometimes during passing of values in function calls, this is done automatically for you - so you can have instances of MyClass that are constants. e.g.
const MyClass instance;
The problem with this is that MyClass has member functions that alter the data members, thus defeating the point of being constant. To protect the data members, the compiler will not allow and constant to call members that alter data members. Unfortunately, you have to tell it which ones these are. That's where the const keyword at the end of the function declaration comes in. The compiler will also check to make sure that constant functions do not alter data members.

The result of all this is that, if you want to create instances of MyClass that are constants, they can only call GetName() since it is the only constant function declared. It is a good idea to declare ALL accessor functions as constant functions as well as any other function that doesn't alter data members.
=================================================

You put the interface in headers and the definitions in a source file. The whole point of splitting these up is that you only want to compile your code once (the source file) but you need to let other files know what functions are available (the header). C# and Java let you define your functions within the class definition. You can do this is C++ as well (the former two languages are based on C++ anyway) but it is not a good idea. C# and Java have neglected the principle of encapsulation - the principle whereby you only make public what is necessary and keep everything else hidden - although C# does give you a workaround by letting you create partial classes.

You seem to have a misunderstanding of what an ADT actually IS. I don't like this term - it's very pretentious. I prefer the term "User-defined Type" since that's precisely what is is. ADT's are nothing more than data types that are not predefined by the C++ language.

Predefined types include: char, int, float, etc..
User-defined types are made by using the keywords: typedef, struct and class.
==========================================================

I agree with you that the textbook is CRAP. The whole thing about auxiliary functions - utter bullsiht. They're just functions that are allowed access to all members of your class. C&D also redefine common Comp Sci terms: objects, formal/informal parametres. Bull as well

Objects are instances of classes. Variables hold values and objects. Functions define parametres that they will accept and you pass arguments TO functions. e.g.
void MyFunction(int number)
   {
   // some code
   }

// inside main()
MyFunction(28 * year + 2);
Here, "number" is a parametre that MyFunction expects to receive and "28 * year + 2" is the argument being passed to MyFunction to satisfy this parametre.
Re: Is this the way to declare a class?
June 17, 2006 09:15AM
Hi Robanaurochs,

Great feedback, thanks.

The prescribed material was a little vague regarding overloaded operators. Here I'm looking specifically at hte differetiation between pre and postfix operators. Perhaps you could elaborate on the difference between the declaration and definition between the two.

Regarding C#, encapsulation and data hiding are defintley possible. Perhaps not as clear cut as in C++. Most VB and C# speak only of Get/Set functions, or using only Get (VB read only) but I have not yet come accross the explicit explanation of Inspectors, Mutators and Facilitators as in C++.

Thanks for the clarification/simplification of ADT to User defined types. ADT sounds very impressive but as you say, it's nothing more than a user defined type.

Using namespace std. I see you have connected this to the "include <string> directive. I was always under the impression the std was a namespace within iostream, and not string. Could you clarify this.

Thanks again for the help, cheers.

AndreB
avatar Re: Is this the way to declare a class?
June 17, 2006 03:01PM
You can imagine that all operators are merely functions that are called in a weird way. The following two statements are equivalent in C++:
sum = 15 + year;
sum = operator+(15, year);
With this in mind, you can overload most of the operators just like you can overload ordinary functions. Like everything else in life, there are a few exceptions: there are a few that you can't overload; and operators overloads that are class members are declared differently from those that are global (outside a class, available to everything).

The prefix and postfix versions of the increment and decrement operators differ only in a sublte way. The prefix operator will act on the variable before returning a result and the postfix operator will return the value before altering it. You can follow the two versions by looking at the following:
// Prefix increment operator
int operator++(int &value)
  {
  value = value + 1;
  return value;
  }

// Postfix increment operator
int operator++(int &value, int)
  {
  int tempSave = value;
  value = value + 1;
  return tempSave;
  }

Because the prefix and postfix have the same function names, the c++ creators had to create some way of distinguishing them apart. This is what the second int is for in the second function above. It has no meaning and doesn't pass an intelligent value. That's why, in the declaration, it hasn't been given a variable name - it's just shown to be there.

When you want to overload an operator to accept a user-defined type, you have two choices: you can make it a global function, or you can make it a member function of that class. The difference is subtle.

When you overload as a global function, you declare the function as it is above (with a variable of that class are the first parametre) but you don't have access to any protected or private members.

When you overload it as a member function, you have access to all the function and data members and, in addition, because the function is part of the class, the class is assumed already so you don't have to pass it as a parametre. e.g. Suppose you have a class that represents a date. You can add days to the date using a global function or a member function.
MyDate operator+(MyDate &date, int daysToAdd)
  {
  MyDate newDate = date;
  newDate.AddDays(daysToAdd);
  return newDate;
  }
This function can be called equivalently as either of:
FinishDate = StartDate + 20;
FinishDate = operator+(StartDate, 20);
To do the same thing as member functions:
class MyDate
  {
  public:
  // other functions
    MyDate operator+(int daysToAdd);
   // rest of class definition
  private:
    int m_daysSince1AD; Total days since 1 Jan 1 AD
  };

MyDate MyDate::operator+(int daysToAdd)
  {
  MyDate newDate;
  newDate.m_daysSince1AD = m_daysSince1AD + daysToAdd;
  return newDate;
  }
Once again, the following two statements are equivalent.
FinishDate = StartDate + 20;
FinishDate = StartDate.operator+(20);
===================================================
C++ has no equivalent to the Get/Set functionality of c# (one of the few things that it's missing). The terms that are mentioned are once again very pretentious terms. Accessors/Manipulators/Inspectors, etc. are merely functions that either retrieve values, change values or just do something with the values. There is absolutedly no need to give them special classifications - they're just ordinary functions. I fear that they are terms that C&D invented to help them sound more intelligent. I've not seen any need where the terms are necessary. I just call them functions the return, change or use values.

===========================================================
Hmm, back to namespaces again.

With all languages, there's the core language and then there's a common library of functions and classes written afterwards.

These libraries are collections of tools written by the language that are such common tasks that it seems a pity for each user of the language to write them themselves. Examples range from simple mathematical functions to complicated routines that create windows on the screen.

In Java, whenever you import something, you're not pulling anything from the core language, you're including something from the standard library. The same from C# when you say something like "using System"

In C++ the standard library is pulled into your programme by using the "#include" directive. The most fundemental part of the standard library is included by default in every programme (the code that starts and shuts down your programme before and after function main()). The rest you have to specify. All parts of the standard library are included using angled brackets e.g. "#include <cassert>".

A subset of the standard library is called the Standard Template Library, or STL and these are the most commonly included files and most useful parts of the standard library. They include <string>, <iostream>, <fstream>, etc. (look in C&D Appendices B and C as well as throughout the book).

The concept of a namespace arises from the fact that different groups of programmers have the possibility of creating useful classes and functions using the same names. If you include files from two different companies that have classes with the same names, you will get name-clash compilation errors. To solve this, the creators of c++ proposed the ability to wrap everything inside a namespace. The name of the namespace that is used by the standard library is std. Java have held on to the concept of namespaces although it is more subtle (Java calls them packages).

People find it a bit tedious to keep writing the fully qualified name of a class, e.g. The full name of a string is std::string and the standard output is called std::cout. To get around this, C++ allows you to globally unwrap a namespace and expose everything by using the "using namespace" command. You can do this for the whole namespace or just a specific class or function.
using namespace std; // uncovers the entire standard library

using std::cout; // only uncovers cout
In the second case, if you include <iostream> you will be able to use cout without having to prefix the namespace but you'll still have to write std::endl. See Appendix D of C&D for more on namespaces.

The reason it's a bad idea to uncover namespaces in header files is because you could cause a name clash in somebody else's programme. Let me give you an example.

Suppose you are writing a few classes for somebody who wants to make a fantastic new programme. You write the classes and use the string class from the STL but you include it in a header file and put "using namespace std;" in the header as well. You compile your classes into a library file and give the library and header files to your client.

Your client doesn't like the way the STL has created the string class and has written his own class that's more appropriate to his needs. He has called his class "string". PROBLEM. this is the same as the name from the STL. Your client will be a little more than pi**ed when he can't compile your code in his programme.

You could have solved this problem if you kept the STL wrapped up in its namespace in the header files and only uncovered it in your source code. Thus your client will use his own class called "string" and you'd be using the one from the STL called "std::string". These are two different names and won't cause a name clash.

This is a silly little example but it illustrates a very important concept. NEVER UNCOVER A NAMESPACE IN A HEADER FILE
Re: Is this the way to declare a class?
June 17, 2006 06:28PM
thanks for clearing a couple of things up for me, robanaurochs. there's a couple of things that'll take a bit to sink in, but it's much clearer then what the book could do.

thanks again.

cool smiley
Re: Is this the way to declare a class?
June 17, 2006 06:35PM
Hi Robanaurochs,

Once again thanks for the comprehensive feedback. You have clarified quite a few of the things I have been struggling with.
The difference between the pre and post fix operators is indeed subtle, but I cannot imaging why they have neglegted to address this issue in both C&D as well as the tutorial letter.

Thanks for the clarification of namespace std. Your explanation of why you should not include a namespace in a header file makes perfect sense.

Cheers,
AndreB
Re: Is this the way to declare a class?
June 18, 2006 05:11PM
robanaurochs, i need some more help with pre and post increments. i just cant seem to get my operator++ code bit to work. below is what i've done and where:

//my date.h file

class Date
{
public:
Date();
Date(int day, int month, int year);
Date &operator++();
private:
//three vars
};

//my date.cpp class

Date& Date:: operator++()
{
SetDay((GetDay()) + 1);
return *this;
}

Date& Date:: operator++(int)
{
int temp = GetDay();

temp = temp + 1; //i know this is wrong

return temp;
}

and then when i try to call something like ++mydate i get error upon error. i am at a complete loss. but strangely enough i dont have any problem with operator+...
Re: Is this the way to declare a class?
June 18, 2006 05:55PM
Dont worry, i cant belive it but i placed the & by the wrong date
Date& Date:: //wrong
instead of
Date &Date::

fcuk
avatar Re: Is this the way to declare a class?
June 18, 2006 06:00PM
If you're going to overload both pre- and postfix forms, you must put both the function declarations in the the class definition as well
Re: Is this the way to declare a class?
June 20, 2006 01:55PM
Thanks Rob - your contribution is greatly appreciated. You really have simplified matters.

For all students looking for a user-friendly C++ book should download LEARNING TO PROGRAM WITH C++ by JOHN SMILEY.

Contact me if you have difficulty downloading - dbn_boy@hotmail.com
avatar Re: Is this the way to declare a class?
June 20, 2006 06:51PM
hmm, I didn't read your previous post closely enough. Please note that in c++, the compiler tries to recognise the largest allowable entity it can and it ignores all whitespace (spaces, tabs, newlines, etc,). Thus, the compiler sees the following as being exactly the same things:

Date&Date::operator++
Date &Date::operator++
Date& Date::operator++
Date & Date::operator ++

Since identifiers can't have the character & in them, the longest entity is an identifier with the name Date followed by a reference operator and another identifier and the scope operator. Theoretically, the only time c++ will require you to put in whitespace is when you've got two identifiers next to each other that would otherwise be interpreted as a single identifier.

It is quite acceptable to write an entire programme without a single space or newline.
Sorry, only registered users may post in this forum.

Click here to login