Thread: constructor

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    291

    constructor

    Say Im making a class bah and I've made this constructor

    Code:
    bah::bah (char* c)
    {
    char * pointer = c;
    
    }
    Is the above a good constructor ?

    Or would this be better :
    Code:
    bah::bah(char* c)
    {
    char* pointer = new char[strlen(c)];
    for (int counter=0; counter < strlen(c); counter++)
       pointer[counter] = c[counter];
    
    }
    This has not be compiled, just of the top of my head.

    Just wondering if there is any difference between them besides the obvious length of code ?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well, in the first case, pointer will be attached to c, thus, any changes made outside to c will be reflected in pointer. In the second case, pointer becomes a copy of c and thus "owns" that memory. In the second case, don't forget to free the memory when you're done. Anyway, they are two very different operations and not used for the same reasons...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    No they're both rubbish!

    Code 1 assigns to a local variable, which will be lost as soon as the constructor completes.

    Code 2 is a horrible way to copy a string and doesn't take into account the null terminator, which would cause you all sorts of problems. However, it isn't a problem, because again the pointer is local and will be lost also, resulting in a memory leak.

    What do you want to do? Copy a string at the constructor? Or just hold pointer to an persistent string? They are both different techniques as Sebastian says.

    Try this. Set your class declaration to look like this.

    Code:
    class blah
    {
    private:
      char* pCPtr;
    public:
      blah(char* c);
      ~blah();
    };
    Notice I've put in a char* in the private section. All methods of the class will be able to see this, and it exist as long as the object exists.

    If you want to hold pointer to an external persistent string, do the following:

    Code:
    blah::blay(char* c)
    {
      pCPtr = c;  
    }
    Here we have passed it a pointer to a character array. The constructor has assigned pCPtr to point to the same thing. There is no need to worry about freeing the char array within the blah class because it is assumed that the memory contents will be deallocated externally. What ever c points to should remain persistent for as long the blah class needs to use pCPtr. If the memory contents are freed, pCPtr would then point to an invalid address.

    If you want to make a copy of the string pointed to by c, then do this:

    Code:
    blah::blah(char* c)
    {
      int len = strlen(c);
      pCPtr = new char[len+1];
      strcpy(pCPtr, c);
    }
    Notice I have created an array 1 longer than the string length. This to make room for the NULL terminator, which is how C/C++ knows where strings end.


    In this case, with have created a new memory resource, and copied the contents pointed to by c into it. If the contents of c later become invalid or change, it doesn't matter because we have a seperate copy.

    However, the blah object is responsible for deallocating the memory of pCPtr, because it created it. You should do this in the destructor, as follows:

    Code:
    blah::~blah()
    {
      delete[] pCPtr;
    }
    Last edited by Davros; 10-30-2002 at 12:26 PM.
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

  4. #4
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    Originally posted by Davros
    No they're both rubbish!

    Code 1 assigns to a local variable, which will be lost as soon as the constructor completes.

    Code 2 is a horrible way to copy a string and doesn't take into account the null terminator, which would cause you all sorts of problems. However, it isn't a problem, because again the pointer is local and will be lost also, resulting in a memory leak.

    What do you want to do? Copy a string at the constructor? Or just hold pointer to an persistent string?
    Sorry, obviously I should have declared the char* pointer in the header file as a private member.

    Code:
    class bah
    {
       public:
       bah(char* c);
       private:
       char* pointer;
    };
    
    bah::bah(char* c)
    {
       pointer = c;
    }
    
    // or
    
    
    bah::bah(char* c)
    {
       int index=0;
       while (c[index++] != '\0')
       {}
    
       pointer = new char[index+1];
    
       for (int counter=0; counter < (index); counter++)
          pointer[counter] = c[counter];
    
       pointer[index+1] = '\0';
    }
    First of all Im interested in the difference between the two constructor above ?

    And yes, Im trying to copy a string to the constructor but without using any library function.

  5. #5
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    I have edited my earlier reply so that it is more constructive. Hope it helps.
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well, if c is a char literal (ie: bah b("Bah"); ) that you're never going to alter, then go with the first. But if you're going to be messing with the memory afterward (ie: bah b("Bah"); b.pointer[0] = 'k' then you will have to use the second method, since char literals are const, and cannot be altered, lest you want to chance crashing your computer!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    Originally posted by Davros
    I have edited my earlier reply so that it is more constructive. Hope it helps.
    Thanks for your reply

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-10-2008, 08:38 PM
  2. C++ have a constructor call another constructor
    By QuestionC in forum C++ Programming
    Replies: 4
    Last Post: 05-17-2007, 01:59 AM
  3. Replies: 3
    Last Post: 03-26-2006, 12:59 AM
  4. Need help in classes
    By LBY in forum C++ Programming
    Replies: 11
    Last Post: 11-26-2004, 04:50 AM
  5. Constructor with Parameter not Firing
    By BillBoeBaggins in forum Windows Programming
    Replies: 4
    Last Post: 08-26-2004, 02:17 PM