?
Solved

new problem on basics of pointers

Posted on 2003-03-16
8
Medium Priority
?
301 Views
Last Modified: 2010-04-01

can some body tell me why the following code is not working?

____________________________________________________________

#include <iostream>
#include <string>

using namespace std;

//dynamic memory allocator

//function by reference

//function array and pointers

//function by pointer


class person

{

private:
     string name;
public:
       void setname();
      void printname();

};


void person::setname()

{


cout<<"Enter Name: ";
cin>>name;

}

void person::printname()
{


cout<<"The Name: " << name;


}



void get(person * &a1, int &n)

{

     cout<<"Enter the number of Instances:";
     cin>>n;

          a1= new person[n];

     for(int i=0;i<n;i++)

     {
     
     a1[i].setname ();
     
     }


}

void main()

{

person *alps;
int k=0;

get(alps,k);

     for(int i=0;i<k;i++)

     {
     alps[k].printname();
     
     }
     

}





0
Comment
Question by:anshuma
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
8 Comments
 
LVL 3

Expert Comment

by:Kashra
ID: 8148772
Well, there's not much wrong with your class (except the lack of constructors and destructors, but that's not why your program doesn't work).


Just change your main function to this, and you'll be fine:

void main()
{
  person *alps;
  int k=0;

  get(alps,k);
      for(int i=0;i<k;i++)
           alps[i].printname();
}

You used alps[k] in your main function instead of the counter in your for loop, i. k's value is 4 when you call alps[k], which is out of range.
0
 

Author Comment

by:anshuma
ID: 8149053
Thank you so much kashra. Can you please tell me something about - lack of constructors and destructors. I want to improve my programming skills asap.
0
 

Author Comment

by:anshuma
ID: 8149084
One more thing, despite the program is working. I am just creating the memory for the class and infact i am creating
the dynamic array of class person.


But here i am not creating a new instance of the class. How come the program is still working

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Accepted Solution

by:
Kashra earned 80 total points
ID: 8149148
Well, first about constructors and destructors:

Those are special kinds of functions that are a good idea to have in any class you make. Its useful to get into the habit of writing them, because for more complicated classes you'll need to use them and need to know what they are for.

Constructor:
The constructor is used to initialize new instances of the class. It is called whenever you create an instance of the class. In the constructor, you should give the variables in your class default values. The "default" constructor is the one that is called without arguments.
You can overload constructors as well, so that you can pass arguments for initialization.
Constructor functions have the same name as the name of the class they belong to.

Destructor:
A destructor is called when the class goes out of scope. It's a "cleanup" function that deletes any dynamically created variables to free up the memory taken up by the class. If you don't use dynamic memory, chances are your destructor will be empty, but its a good thing to write in just for style.
Destructors have the same name as the name of the class they belong to, preceded by a ~.

Here's an example of your class with constructors and destructors:

class person {
   private:
       string name;
   public:
       // Default constructor, creates a default person
       // by the name of "John Doe"
       person()
          { name = "John Doe"; }
       // Overloaded constructor, creates a person with
       // a specified name
       person(string tmpName)
          { name = tmpName; }
       // Copy constructor, creates a person from another person
       person(person &someone)
          { name = someone.name; }
       // Destructor, cleans up a person after you kill him ;)
       ~person() {}

       void setname();
       void printname();
};

And, with these constructors, you can create person objects in the following ways:
int main()
{
   person A; // Will be named "John Doe" by default
   person B("Kashra"); // Will be named Kashra
   person C(B); // Uses copy constructor, will also be named Kashra
}

When you get into inheritance and more advance object-oriented programming, you'll learn to love (and hate) them, don't worry.
0
 
LVL 3

Expert Comment

by:Kashra
ID: 8149165
I'm not sure what your second question is asking, but I'll try to answer it.

When you call:
   a1= new person[n];
What you're doing is creating n instances of your person class, calling its constructor n-times, allocating the memory for them in one big block, and returning a pointer to the first member of the array. (At least that's what I think you're doing).

From that point on, your classes are there, in memory, and at some point you have to remove them.

As another note, good programming habits would include a "delete [] a1;" statement somewhere in your program to free up the memory you allocated.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8150949
Actually the lack of constructors and destructors in his case is just fine.

The default ones provided by the compiler works just fine for your case.

Part of the reason for this is that you've been smart and used std::string instead of char * in your person class.

If you had written:

class person {
private:
   char * name;

public:
   ....
};

You would need a destructor and constructor to properly handle the pointer to the name.

Since you let the string class handle the name you don't need any constructors or destructors on your own in this particular case.

If you had other variables or restrictions this might quickly change though so don't take this as an "it is always ok to omit constructors/destructors" thing. It works fine in this particular case is all I am saying.

Alf
0
 
LVL 3

Expert Comment

by:Kashra
ID: 8153649
Like I said, this particular program will work just fine without them, but its a good habit to start writing them explicitly whether you need them or not. It just depends on how much you like to trust things to the compiler.

A little story just for the sake of it: I was using the std::string class a few months back and compiled using gcc on an older IRIX-based machine. My code used no dynamic memory allocation, and yet when I ran it I saw this gigantic memory leak...about 10MB every couple of seconds...until it core-dumped.

After about a full day of troubleshooting and two other people looking at my code, I realized that it was a problem with the std::string class destructor. I suppose that version of the libraries was reeeaaallly old, but none of my strings were being destroyed properly.

Now I love the std::string class, don't get me wrong. I'm just saying not to have any blind trust in it.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8153769
Actually I will give the opposite advice of Kashra there.

C++ writes pretty decent and efficient constructors for you if you dont' declare any in all cases except when you need a deep copy and when you need explcite values in the class members.

Times when you don't need explicite values for class members are:

1. If you don't care about the value when default constructor is called.

class point {
private:
  double x, y;
public:
   point() {}
};

This constructor is essentially useless. It doesn't initialize the vlaues and the default one made by C++ already does what it does. Just drop it.

2. If all your elements that require specific values have their own constructors.

class X {
private:
   string name;
public:
   X() {}
};

This time we do want a specific value in the string, but the string constructor takes good care of that and X's constructor therefore ends up doing nothing. C++ can handle this just as well as you do so drop that constructor.

Copy constructors are also often not needed:

class point {
private:
   int x, y;
public:
   point(const point & p) : x(p.x), y(p.y) {}
};

This copy constructor doesn't do anything beyond what C++'s own default one does and so it is rather useless and C++'s default one can actually be implemented faster than your own so this constructor should go as well.

Constructors ARE needed when you need any of the following features:

1. Control access to a constructor.

class point {
private:
   int x, y;
   point() {}
public:
   ...
};

Here the constructor itself is no different from the previous, but it has private access. The default one would have had public access so writing your own limits the access of that constructor.

2. You need to initialize certain values. The reason why you need to initialize can vary, either to establish an invariant or just to have well defined values for your members. In this case the constructor is the plcae to do that:

class list {
private:
   node * first;
   node * last;
   int count;

public:
   list() : first(0), last(0), count(0) {}
};

Here you set up the invariant that count keep track of how many elements you have in the list etc.

3. If you need a deep copy of members you need a copy constructor and probably also an assignment operator.

To the list from previous situation, if you want to copy the list you probably don't want to just do a raw copy of the pointers. If you did, the two list objects would share the list and chaos would take over when one of them start to insert and remove elements from its list and the changes are completely or partially shown in the other list. To avoid this, it is best to make a new list with the same elements as the original list:

class list {
private:
   node * first;
   node * last;
   int count;

public:
   list(const list & lst)
      : first(0), last(0), count(0)
   { add_list(lst); }

   list & operator = (const list & lst)
   { clear(); add_list(lst); return *this; }

   list & clear(); // remove all elements in list.

   // add elements of list lst at the end of this list.
   list & add_list(const list & lst);
};

Similar considerations appear for destructor also. However, you seldom want to limit access to destructor since destructor can be called from several places in the code so the access limitation isn't so common for destructor.

A destructor that does nothing is often useless however, but in some cases it is not:

1. When it is declared in the baseclass and it is virtual.

This tells C++ that destructors of this class and all classes derived from it are virtual and so even though the destructor does nothing it is still useful.

class B {
public:
   virtual ~B() {}
   virtual int func() = 0;
};

Such a class that is intended to be the baseclass of an hierarchy should always have a virtual destructor - the only reason why it shouldn't is if you don't want any virtual functions in it and if it is a baseclass that is normally not the case.

The reason is that if you have a class derived from B:

class A : public B {
....
};

and you do:

B * bp = new A;

and then do:

delete bp;

you want the destructor for A::~A() to be called and it can only be called if the destructor B::~B() is declared to be virtual.

Alf
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses
Course of the Month12 days, 17 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question