few questions concerning classes

A

alternativa

Hello,
I have a few questions concerning classes.

1)
Why some people use default constructos, i.e constructors with no
parameters? To me it doesn't make any sense, is there something I
should know? For example, I'd declare a class in a following way:
class Sample {
int number;
string title;
public:
Sample (int n, string t);
~Sample ();
}

What is the sense in adding also
Sample() {}; in public part of a class?

2)
If I have a few classes containing lists and one main class containing
head pointers to these lists, should I write destructors for all the
classes separately, or is it enough to write a destructor for main
class only? For example:

class Numbers {
int num;
Numbers *numNext;
public:
Numbers () { /*constructor body*/ };
~Numbers () { /*empty*/ };
};

class Titles {
int tit;
Titles *titNext;
public:
Titles () { /*constructor body*/ };
~Titles () { /*empty*/ };
};

class Together {
*numHead;
*titHead;
public:
Together (){ /*constructor body*/ };
~Together(){ /*destructor body*/ };
};
Is this ok?

3) inheritance problem
I've got the following base class:

class Person {
public:
string name;
int phone;
Person(string n, int p);
~Person();
}

and inherited class:

class Student {
int mark;
public:
Student(string n, int p, int m) ;
~Student();
}

I know I shoudl write the base class in a way that data are in a
private part,but then it doesn't work. How to deal with it?
 
O

osmium

alternativa said:
I have a few questions concerning classes.

1)
Why some people use default constructos, i.e constructors with no
parameters? To me it doesn't make any sense, is there something I
should know? For example, I'd declare a class in a following way:
class Sample {
int number;
string title;
public:
Sample (int n, string t);
~Sample ();
}

What is the sense in adding also
Sample() {}; in public part of a class?

Consider this.

int a = 1024;
int b = 2048;
int c = 4096;
c = a + b;

This gives the impression that knowledge exists and it is simply fraud.
There is no meaning at all to the value given when c is defined. It
misleads people.

That alone should be sufficient reason. If not, you can not have an array
of objects unless there is a default constructor.
Note also, that as soon as you declare a constructor the default constructor
goes away, you have to explicitly bring it back, as above.

<snip>

I don't like multiple part questions. It's hard enough to keep one single
thread on track.
 
J

John Carson

alternativa said:
Hello,
I have a few questions concerning classes.

1)
Why some people use default constructos, i.e constructors with no
parameters? To me it doesn't make any sense, is there something I
should know? For example, I'd declare a class in a following way:
class Sample {
int number;
string title;
public:
Sample (int n, string t);
~Sample ();
}

What is the sense in adding also
Sample() {}; in public part of a class?

In some contexts, it is not possible to call anything other than a default
constructor, e.g.,

Sample * array = new Sample[10];

It is also sometimes the case that

a) a class has no data members, or
b) it is not known at the time of declaration what those data members need
to be initialized to.

2)
If I have a few classes containing lists and one main class containing
head pointers to these lists, should I write destructors for all the
classes separately, or is it enough to write a destructor for main
class only? For example:

class Numbers {
int num;
Numbers *numNext;
public:
Numbers () { /*constructor body*/ };
~Numbers () { /*empty*/ };
};

class Titles {
int tit;
Titles *titNext;
public:
Titles () { /*constructor body*/ };
~Titles () { /*empty*/ };
};

class Together {
*numHead;
*titHead;
public:
Together (){ /*constructor body*/ };
~Together(){ /*destructor body*/ };
};
Is this ok?

You haven't given the type of numHead and titHead. I presume you mean:

Numbers *numHead;
Titles *titHead;

Whether it is OK depends on the nature of the destructor. In Together's
destructor, you could iterate along each list and delete each link. It is
much simpler, however, to write:

~Numbers () { delete numNext; }
~Titles () { delete titNext; }
~Together(){ delete numHead; delete titHead; }

Simpler still is to use std::list.
3) inheritance problem
I've got the following base class:

class Person {
public:
string name;
int phone;
Person(string n, int p);
~Person();
}

and inherited class:

class Student {
int mark;
public:
Student(string n, int p, int m) ;
~Student();
}

I know I shoudl write the base class in a way that data are in a
private part,but then it doesn't work. How to deal with it?

"Doesn't work" isn't very helpful information. How doesn't it work? What are
you trying to do?
 
A

alternativa

"Doesn't work" isn't very helpful information. How doesn't it work? What are
you trying to do?

When I try to compile the program which also contains some other
methods of derived class (for example method printing the data of
derived class - of course of a base class also), then it is not
possible and the comment is 'class string Person::name' is private'.
When I put 'protected' instead of 'private' in basic class Person, then
it's okay, but I have some doubts whether it's the best solution.
regards,
a.
 
J

John Carson

alternativa said:
When I try to compile the program which also contains some other
methods of derived class (for example method printing the data of
derived class - of course of a base class also), then it is not
possible and the comment is 'class string Person::name' is private'.
When I put 'protected' instead of 'private' in basic class Person,
then it's okay, but I have some doubts whether it's the best solution.
regards,
a.


You can get around in in various ways. For example, the base class could
have a public or protected PrintData function. The PrintData function in the
derived class would first call the PrintData function from the base class
before outputting its own data.

For more flexibility, the base class can have (public or protected) accessor
functions that return either copies of the data (so modifying the returned
data doesn't affect the data stored in the base class instance) or const
references to the data (so the returned data can't be modified). The
functions in the derived class that need read-only access to the base class
data can access it through these functions.

If the derived class actually needs to modify the data in the base class,
then the base class can provide functions for modifying the data. These
functions can do range checks or whatever else may be deemed necessary to
provide for "safe" modifications.
 
S

Salt_Peter

alternativa said:
Hello,
I have a few questions concerning classes.

1)
Why some people use default constructos, i.e constructors with no
parameters? To me it doesn't make any sense, is there something I
should know? For example, I'd declare a class in a following way:
class Sample {
int number;
string title;
public:
Sample (int n, string t);
~Sample ();
}

What is the sense in adding also
Sample() {}; in public part of a class?

Default ctors are sometimes required (ie: primitive containers). They also
help you define what a default object looks like. That can help you in so
many ways. By the way, your Sample class above has no def ctor, the compiler
will not generate one for you.

#include <string>

class Sample
{
int number;
std::string title;
public:
Sample() : number(0), title("unknown") { } // def ctor
Sample(int n, std::string s) : number(n), title(s) { }
~Sample () { }
};

int main()
{
Sample samples[10]; // all 10 elements are inited with 0 and "unknown".
}
2)
If I have a few classes containing lists and one main class containing
head pointers to these lists, should I write destructors for all the
classes separately, or is it enough to write a destructor for main
class only? For example:

class Numbers {
int num;
Numbers *numNext;
public:
Numbers () { /*constructor body*/ };
~Numbers () { /*empty*/ };
};

class Titles {
int tit;
Titles *titNext;
public:
Titles () { /*constructor body*/ };
~Titles () { /*empty*/ };
};

class Together {
*numHead;
*titHead;
public:
Together (){ /*constructor body*/ };
~Together(){ /*destructor body*/ };
};
Is this ok?

Not really. Titles and Numbers look like the components of the previous
Sample class. Why not just build a list of Samples instead of banging your
head with pointers? Goal #1 is to never, ever use pointers unless absolutely
neccessary.

std::list<Sample> samples;
samples.push_back(0, "title zero");
samples.push_back(1, "title one");
3) inheritance problem
I've got the following base class:

class Person {
public:
string name;
int phone;
Person(string n, int p);
~Person();
}

and inherited class:

class Student {
int mark;
public:
Student(string n, int p, int m) ;
~Student();
}

I know I shoudl write the base class in a way that data are in a
private part,but then it doesn't work. How to deal with it?

with init lists...
The data should be encapsulated otherwise you can't guarentee nor control
the state of the objects the classes create. Don't forget your semicolons
when you declare your classes. Inheritance is propagated by you, not the
compiler. You have to tell the compiler what the relationship between
classes are.

#include <iostream>
#include <ostream>
#include <vector>
#include <string>

class Person
{
int id;
std::string name;
public:
Person(int n, std::string s) : id(n), name(s) { }
~Person() { }
/* member functions */
int getID() const { return id; }
std::string getName() const { return name; }
};

class Student : public Person // ie: a Student is_a Person
{
double mark;
public:
Student(int n, std::string s, double d) : Person(n, s), mark(d) { }
~Student() { }
/* member functions */
double getMark() const { return mark; }
};

int main()
{
std::vector<Student> students;
students.push_back(0, "Annie", 75.1);
students.push_back(1, "Bob", 65.5);
students.push_back(2, "Cathy", 70.9);

for (int i = 0; i < students.size(); ++i)
{
std::cout << "id: " << students.getID(); // a Student is_a
Person
std::cout << " name: " << students.getName();
std::cout << "\tmark: " << students.getMark();
std::cout << std::endl;
}
}

Set breakpoints and step into the ctors and into the member functions to get
the picture.
If std::vectors are baffling you, ask someone to give you an example with a
dumb array. Unfortunately, that would mean def ctors + setter functions.
 
M

Markus Schoder

Salt_Peter said:
int main()
{
std::vector<Student> students;
students.push_back(0, "Annie", 75.1);
students.push_back(1, "Bob", 65.5);
students.push_back(2, "Cathy", 70.9);

This is supposed to compile? You probably meant:

students.push_back(Student(0, "Annie", 75.1));
students.push_back(Student(1, "Bob", 65.5));
students.push_back(Student(2, "Cathy", 70.9));
 
S

Salt_Peter

Markus said:
This is supposed to compile? You probably meant:

students.push_back(Student(0, "Annie", 75.1));
students.push_back(Student(1, "Bob", 65.5));
students.push_back(Student(2, "Cathy", 70.9));

Yep, thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top