0

i am having trouble with my code. I am abit stumped. I have a data member which is a pointer to a string type. I use the constructor as a defualt initialer to this pointer, then when I call an object in the main function the intialised pointer to points to the memory address where the string is stored and prints the contents. That is what is supposed to happen, but I can't get the program to work. May somebody please tell me where I am going wrong?

#include<iostream>
#include<string>

using namespace std;

class NoName{
public:
    NoName(string &sName("Alice In Wonderland") ){};
private:
    string *pstring;
};

int main(){
    //the constructor will be automatically called here once a object is created
    // and the string "Alice in Wonderland" will appear on the screen
    return 0;
}
MGZero
  • 5,812
  • 5
  • 29
  • 46
  • The code you posted does not do what you say it does. Also, your constructor declaration does not do what you *think* it does. – us2012 Feb 08 '13 at 16:11
  • I think you have a lot of learning to do regarding constructors, pointers and references. – MGZero Feb 08 '13 at 17:50

3 Answers3

5

Just simply use a std::string member and initialize it in Member initializer list:

 private:
    string mstring;

 public:
    NoName():mstring("Alice In Wonderland"){} 

You could also let the constructor take in a parameter instead of hardcoding the string and let the user pass the string at run-time:

NoName(std::string str):mstring(str){}

You do not need a pointer. By using a pointer to std::string You nullify the advantages of implicit manual memory management offered by std::string.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I'm working out of a book that specifies the use of a pointer, as you can see I am abit confused on how to go about this. Would appreciate helpful comments please. – A Big Ball Of Lettuce Feb 08 '13 at 16:16
  • @Josh: In that case You really need a new book. [Here you go](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Also read about the Member Initializer list link added inline to the answer. It should help you understand better. – Alok Save Feb 08 '13 at 16:17
  • Yes the book comes from that list. Clever answers aside, is there anybody who can look at my horrendous code and tell me exactly how to fix it? Much appreciated. – A Big Ball Of Lettuce Feb 08 '13 at 16:19
  • @Josh well, is your class supposed to own the string pointer to, or not? – juanchopanza Feb 08 '13 at 16:21
  • *"Clever answers aside"*??? Or Do you really mean *Provide me the code?* Did you even read the link inline to the answer? – Alok Save Feb 08 '13 at 16:44
  • @AlokSave I think he may have been alluding to the rude comments attached to his question. – Dave Rager Feb 08 '13 at 16:52
  • @Dave Rager: I don't encourage such rudeness and in all sincerity I answered OPs question and a little effort should be enough to solve the problem but OP refuses to do that and its disappointing. – Alok Save Feb 08 '13 at 16:59
  • thank you for speaking on my behalf @Alok, except you are completely wrong in assuming that I have made no attempts to answer this question. Allow me to correct your ignorance: I am making attempts to answer this question. I clearly need a better understanding of classes and pointers. I can correct my lack of understanding, but can the majority of smartasses correct their arrogance? – A Big Ball Of Lettuce Feb 08 '13 at 18:08
2

If you really need to store a pointer for some reason, then there are some points to remember:

  • Pointers are initialized like new Class
  • Prefer to initialize class members in the member initializer list
  • Any time you write the word new think about where you're going to write delete. (In this case it goes in the destructor.
  • Rule of Three: If you need a destructor (you do, because of delete), then you also need a copy constructor and copy assignment operator.

This is one way your code could look: http://ideone.com/21yGgC

#include<iostream>
#include<string>

using std::cout; using std::endl;
using std::string;

class NoName
{
public:
    NoName(string sName = "Alice In Wonderland") :
        pstring(new string(sName))
    {
      cout << "ctor - " << *pstring << endl;
    }
    NoName(const NoName& rhs) :
        pstring(new string(*rhs.pstring))
    {
      cout << "Copy ctor - " << *pstring << endl;
    }
    NoName& operator=(const NoName& rhs)
    {
      *pstring = *rhs.pstring;
      cout << "Copy assignment operator - " << *pstring << endl;
      return *this;
    }

    ~NoName()
    {
        cout << "dtor, my name was " << *pstring << endl;
        delete pstring;
    }
private:
    string *pstring;
};

.

int main()
{
    NoName m, n("Another name");
    NoName o(m);
    o = n;

    return 0;
}

Notice how much easier it is if you don't use the unnecessary pointer:

class Better
{
public:
    Better(string sName = "Alice In Wonderland") :
        m_string(sName)
    {
    }
private:
    string m_string;
};

Because you don't need the custom destructor, you also don't need the copy constructor or copy assigment operator either. Much easier!

Bill
  • 14,257
  • 4
  • 43
  • 55
  • Your example code is a live example of why using a pointer member is not a good idea. You did not follow **The rule of three**, you might argue you never intend your class to be copy constructible but in that case your copy constructor should be declared private. – Alok Save Feb 08 '13 at 17:08
  • True, I was in the middle of editing when something popped up. I'll be fixing it shortly – Bill Feb 08 '13 at 17:15
  • @AlokSave - Hopefully all fixed now. :) – Bill Feb 08 '13 at 17:27
0

You're not using the constructor properly. First of all, you create this reference parameter and try to initialize it to a string object (that's asking for problems). Second, your constructor never actually does anything.

You need to call new on your pointer, dereference it and give the data pointed to a value, output the dereferenced value with std::cout and then clean the memory up with delete in the destructor (or in this case, you can do it after you use cout if you're not planning on using that string again. But do it in the destructor if you need it still).

Assuming you're doing this for a class, your textbook should tell you how to do these things.

EDIT: this is also not the default-constructor. I changed your tag to match appropriately.

MGZero
  • 5,812
  • 5
  • 29
  • 46