You are here:

C++/why is this wrong?

Advertisement


Question
QUESTION: Hello Vijayan,

below i have a working code (version A). if i only change a certain part of the code (version B), i discovered that whenever i run the version B, the cmd screen doesn't show. logically, i think i am correct but mayb, i dont know pls check. the correction has been commented in version B, so you know the adjustment i made to the programme. thanks.

version A:


#include <string.h>
#include<iostream>
using namespace std;

class Person {
  public :
  Person(const char *Pname , int child_Num, int a, int b, int c);
  ~Person();/*the destructor*/
  Person();

  int getChild_Num() {return child_Num;}
  int getChild_Age(int i) {return child_Ages[i];}
  char* getName () {return name;};
  const Person& operator=(Person p);
  Person operator +(Person &p);

  friend ostream &operator<<(ostream &out, const Person& p);

  private:
     char *name;
     int   *child_Ages;
     int    child_Num;
};
         
Person Person::operator+(Person &p)
{
  char   *namemerge;
  int       *childmerge;
  int       nchilds;
  int       i, j;
  
  // the 3 addional spaces is for the " & " part
  namemerge = new char[strlen(name) + strlen(p.getName ())+3+1];
  strcpy (namemerge, getName ());
  strcat (namemerge, " & ");
  strcat (namemerge, p.getName ());

  nchilds = child_Num + p.getChild_Num ();
  childmerge = new int[nchilds];
  
  for (i = 0; i < child_Num; i++)
     childmerge[i] = child_Ages[i];   // move the child ages from this to childmerge
  for (j = 0; j < p.getChild_Num (); j++)
     childmerge[i] = p.getChild_Age (j);// move the child ages from this to childmerge

  Person couple (namemerge, nchilds,
         childmerge[0], childmerge[1],
         childmerge[2]);
  return couple;
}
/*implementation of class methods*/

ostream &operator<<(ostream &out, Person& p)
{
  out << p.getName () << " has " << p.getChild_Num () << " children"<<endl;
  
  return out;
}

const Person& Person:: operator= (Person p)
{
  if(this!=&p)   /*avoid invalid self-assignment*/
  {
     /*allocate address for the new spaces and copy in variables*/

     name = new char[strlen(p.name)+1];
     strcpy(name, p.name);
     
     child_Num = p.getChild_Num ();
       child_Ages = new int[child_Num];
     for(int i =0; i<child_Num; i++)
     child_Ages[i] =  p.getChild_Age(i);
     }
     return *this;/*always do this as a convention*/
   }

// contructor
Person::Person(const char *Pname , int Maxnum, int a, int b, int c)
{
  name = new char[strlen(Pname)+1];
  strcpy(name, Pname);
  child_Ages = new int[3];
  child_Num = Maxnum;

  child_Ages[0] =  a;
  child_Ages[1] =  b;
  child_Ages[2] =  c;
}

// empty contructor
Person::Person()
{
  name = NULL;
  child_Num = 0;

}

Person::~Person()/*implementation of the destructor*/
{
  delete [] name;
  delete [] child_Ages;
}

int main() {
  Person p1("Matti", 3, 10, 12, 16);  //three childen
  Person p2("Maija", 2, 5, 7, 0);  //two childen
  Person couple;

  cout << "Person 1 is:" << p1 << endl;
  cout << "Person 2 is:" << p2 << endl;
  
  couple = p1 + p2;     // Name of the couple is
  // Matti & Maija. They have
  // 5 childen
  cout << "Couple is: " << couple;
  
   system("PAUSE");

  return 0;
}


version B:

#include <string.h>
#include<iostream>
using namespace std;

class Person {
  public :
  Person(const char *Pname , int child_Num, int a, int b, int c);
  ~Person();/*the destructor*/
  Person();

  int getChild_Num() {return child_Num;}
  int getChild_Age(int i) {return child_Ages[i];}
  char* getName () {return name;};
  const Person& operator=(Person p);
  Person operator +(Person &p);

  friend ostream &operator<<(ostream &out, const Person& p);

  private:
     char *name;
     int   *child_Ages;
     int    child_Num;
};
         
Person Person::operator+(Person &p)
{
  char   *namemerge;
  int       *childmerge;
  int       nchilds;
  int       i, j;
  
  // the 3 addional spaces is for the " & " part
  namemerge = new char[strlen(name) + strlen(p.getName ())+3+1];
  strcpy (namemerge, getName ());
  strcat (namemerge, " & ");
  strcat (namemerge, p.getName ());

  nchilds = child_Num + p.getChild_Num ();
  childmerge = new int[nchilds];
  
  for (i = 0; i < child_Num; i++)
     childmerge[i] = child_Ages[i];   // move the child ages from this to childmerge
  for (j = 0; j < p.getChild_Num (); j++)
     childmerge[i] = p.getChild_Age (j);// move the child ages from this to childmerge

  Person couple (namemerge, nchilds,
         childmerge[0], childmerge[1],
         childmerge[2]);
  return couple;
}
/*implementation of class methods*/

ostream &operator<<(ostream &out, Person& p)
{
  out << p.getName () << " has " << p.getChild_Num () << " children"<<endl;
  
  return out;
}

const Person& Person:: operator= (Person p)
{
  if(this!=&p)   /*avoid invalid self-assignment*/
  {
     /*allocate address for the new spaces and copy in variables*/

     name = new char[strlen(p.name)+1];
     strcpy(name, p.name);
     
     child_Num = p.getChild_Num ();
       child_Ages = new int[child_Num];
     for(int i =0; i<child_Num; i++)
     child_Ages[i] =  p.getChild_Age(i);
     }
     return *this;/*always do this as a convention*/
   }

// contructor
Person::Person(const char *Pname , int Maxnum, int a, int b, int c)
{
/*adjustment made here */
  name = new char[strlen(Pname)+1];
  strcpy(name, Pname);
       child_Num = Maxnum;   
  child_Ages = new int[child_Num];
  

  child_Ages[0] =  a;
  child_Ages[1] =  b;
  child_Ages[2] =  c;
}

// empty contructor
Person::Person()
{
  name = NULL;
  child_Num = 0;

}

Person::~Person()/*implementation of the destructor*/
{
  delete [] name;
  delete [] child_Ages;
}

int main() {
  Person p1("Matti", 3, 10, 12, 16);  //three childen
  Person p2("Maija", 2, 5, 7, 0);  //two childen
  Person couple;

  cout << "Person 1 is:" << p1 << endl;
  cout << "Person 2 is:" << p2 << endl;
  
  couple = p1 + p2;     // Name of the couple is
  // Matti & Maija. They have
  // 5 childen
  cout << "Couple is: " << couple;
  
   system("PAUSE");

  return 0;
}


ANSWER: #include <string.h>

There is no such header in ISO C++. Use #include <cstring> instead.



The system() function is declared in <cstdlib> and you need to #include the header.

system("pause") represents a vulnerability (an unsafe programming practice) which can be exploited by an attacker. A malicious attacker could replace the "pause" program on the machine with a program that does some kind of damage, and use it to cause trouble. Spoofing a legitimate and harmless program is a common practice among malware.

In addition, it also has the drawback that the argument string is not portable across different implementations. Your code may work on windows, but may do something completely different (or not work at all) on unix.

A portable and less risky way is to write:

  std::cin >> std::ws ; // throw away white spaces remaining in the input buffer
  std::cin.get() ; // wait for the user to enter a new line  



> i discovered that whenever i run the version B, the cmd screen doesn't show.
> logically, i think i am correct but mayb, i dont know pls check.

I had a cursory look, and both versions of your code appear to be correct, and do run from the command prompt, giving the expected outputs, when I tested them.

What do you mean by "the cmd screen doesn't show"? Are you using an IDE?


---------- FOLLOW-UP ----------

QUESTION: Hi vijayan,

I am so surprised with the rate of the reply. i appreciate it alot. you said this:
"A portable and less risky way is to write:

 std::cin >> std::ws ; // throw away white spaces remaining in the input buffer
 std::cin.get() ; // wait for the user to enter a new line  
"

pls, where is that to b included in my programme bcuz i dont know where to affix those.

Finally, please, i need a very short but clear explanations on the constant methods and members in C++. i am most times confused about constant members and member fuunctions. could you explain this constant concept with a very short c++ example. I do know that when you want to keep the content of a function or member fixed you use the constant keyword but often times, this confuses me as i see it in some functions and mayb they might be correct, my reasoning keeps saying this shouldn't be there. so, i need a short programme or even code explaining this.

Also, is the keyword Static. I also need some explaining with this too. thanks alot. and expecting another sharp reply :)

Answer
> pls, where is that to b included in my programme bcuz i dont know where to affix those.

Just replace

  system("PAUSE");

with

  std::cin >> std::ws ;
  std::cin.get() ;


A const member variable is one that cannot be changed after it is initialized. A const member function is one that does not change the state of the object on which it is invoked. For example,

class Person
{
  public:

    Person( const std::string& n ) : name(n) // initialize name
    {
       // ...
    }

    // ....

    std::string get_name() const  // does not modify the object
    { return name ; }

    // ....

  private:

    // ....

    const std::string name ; // name of a person can never change

    // ....
};

For more details, see http://www.java-samples.com/showtutorial.php?tutorialid=314
and http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.10

In fact, it would be a good idea for you to study all the FAQs in the section:
http://www.parashift.com/c++-faq-lite/const-correctness.html



Members of a class can be declared using the storage class specifier 'static' in the class member list. Only one copy of the static member is shared by all objects of a class in a program. When you declare an object of a class having a static member, the static member is not part of each indivudual object of the class.

A typical use of a static member variable is to keep data common to all objects of a class. static member functions can be used to access or modify such data. For example, you can use a static data member as a counter to store the number of objects of a particular class type that are created. Each time a new object is created, this static data member can be incremented to keep track of the total number of objects.

You access a static member by qualifying the class name using the :: (scope resolution) operator.
An example:

class checking_account
{
        public:

         // ....

         // non-static, each checking_account object has its own balance
         double get_balance() const ; // get the balance for this account

         // static, all objects of type checking_account share a common interest rate
         static double get_interest_rate() ; // get the interest rate common to all checking_accounts

         // ...
     
        private:

         // ....

         // non-static, each checking_account object has its own balance
         double balance ; // balance for this account

         // static, all objects of type checking_account share a common interest rate
         static double interest_rate ;

         // ...
};

double checking_account::interest_rate = 4.50 ;

void foobar( const checking_account& ac1, const checking_account& ac2 )
{
        double d1 = ac1.get_balance() ; // ok, gets the balance for object ac1
        double d2 = ac2.get_balance() ; // ok, gets the balance for object ac2

        //checking_account::get_balance() ; // error, an object must be specified

        double r = checking_account::get_interest_rate() ; // ok, an object is not required
        // gets interest rate common to all checking_accounts
}  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.