Thread: A couple of questions regarding classes and strings.

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    9

    A couple of questions regarding classes and strings.

    Hi all,

    1) In a problem I have to solve, it is required that I create a class with one of the functions in it that returns the total cost of all objects instantiated from that class. Here's the class definition:

    Code:
    class Computer {
    
    public:
    	Computer(char * = "", double = 0.0, double = 0.0, int = 0, int = 0);
    	~Computer();
    	void setPersonName(char *);
    	void setCost(float);
    	void setCpuSpeed(float);
    	void setMonths(int);
    	void setMemorySize(int);
    	char *getPersonName();
    	float getCost();
    	float getCpuSpeed();
    	int getMonths();
    	int getMemorySize();
    	float sell();
    	void ageInSeconds();
    	void printTotalCost();
    
    private:
    	char* personName;
    	double cost;
    	double cpuSpeed;
    	int months;
    	int memorySize;
    	static double totalCost;
    
    };
    The function I am referring to is pringTotalCost(). Anyways, I used the static double totalCost for this purpose and it worked fine; however, is it possible to call the function by just typing "printTotalCost()" instead of computer1.printTotalCost() for example?

    2) How come this works:
    [code]
    Computer::Computer(char *name, double price, double speed, int age, int mem)
    {
    personName = name;
    cost = price;
    cpuSpeed = speed;
    months = age;
    memorySize = mem;
    totalCost += price;
    }[code]

    But not this:

    Code:
    Computer::Computer(char *name, double price, double speed, int age, int mem)
    {
    	setPersonName(name);
    	setCost(price);
    	setCpuSpeed(speed);
    	setMonths(age);
    	setMemorySize(mem);
    	totalCost += price;
    }
    3) How come this outputs the same number of characters I enter regardless of how small I set the size of the array?

    Code:
    char name[10];
    
    cin >> name;
    cout << name;
    I am using MS VS 6.0

    Thanks
    Last edited by Azimuth; 06-10-2004 at 09:37 AM.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >is it possible to call the function by just typing "printTotalCost()" instead of computer1.printTotalCost() for example?
    Not without doing something strange, but if you make printTotalCost static you can say Computer::printTotalCost().

    >2)<snip>
    My first reaction is to say that VC++ 6.0 sucks. ;)

    >3) How come this outputs the same number of characters I enter regardless of how small I set the size of the array?
    Don't do that, it overflows your array and causes undefined behavior. You should be using getline for string input so that you can avoid such problems:
    Code:
    cin.getline(name, sizeof name);
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    9
    When I said "worked" for the second question, I meant that it gave correct results.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >When I said "worked" for the second question, I meant that it gave correct results.
    That doesn't change my answer. Without something I can compile that exhibits your problem, I'm forced to write my own test code. And my test code works for both cases on three popular compilers.
    My best code is written with the delete key.

  5. #5
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    Also, I have vc 6.0, and it works for me. I would assume that it is some where in your code that is the problem.

    And prelude, vc 6.0 > all. :P
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I would assume that it is some where in your code that is the problem.
    But we can't be sure until the OP gives us something more to work with.

    >And prelude, vc 6.0 > all. :P
    Bwahaha!
    My best code is written with the delete key.

  7. #7
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    what compiler do you like prelude?
    Woop?

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    I don't think your class is designed well with all those char*'s. From the look of it, your first example is asigning personName to some pointer. If the pointer it's assigned to is looses its allocation then the object which contains the pointer becomes invalid. You probably want to be using the std::string class.

  9. #9
    Registered User
    Join Date
    Jun 2004
    Posts
    9
    Quote Originally Posted by okinrus
    I don't think your class is designed well with all those char*'s. From the look of it, your first example is asigning personName to some pointer. If the pointer it's assigned to is looses its allocation then the object which contains the pointer becomes invalid. You probably want to be using the std::string class.
    The getPersonName() function is supposed to return the person's name, and it is defaulted to an empty string in the constructor, so is it better if I use the string class as you pointed out?

    And regarding my second question, I discovered something wrong in the implementation of the functions. Now that I fixed it, they're working fine

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >what compiler do you like prelude?
    I like whichever compiler works best for what I'm working on. But that's irrelevant because I'm often forced to use the house compiler rather than my personal preference.
    My best code is written with the delete key.

  11. #11
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    The getPersonName() function is supposed to return the person's name, and it is defaulted to an empty string in the constructor, so is it better if I use the string class as you pointed out?
    It's usually much better. There are also copying issues that you have to deal with when you use pointers within your classes, and that will make your code much more complicated.
    Nevertheless, your code will work with the default empty string because the the memory for it allocated statically, meaning the array pointing to the string does not get deallocated until the program ends.

    For getPersonName, I would usually return const std::string& but you could also return char* if you the c_str() method function from std::string. You might also want to make your accessors constant by writing char* getPersonName() const.

  12. #12
    Registered User
    Join Date
    Jun 2004
    Posts
    9
    Quote Originally Posted by okinrus
    You might also want to make your accessors constant by writing char* getPersonName() const.
    I'm currently doing a summer session in university and I'm taking a course called "Introduction to computer science II" which deals with OOP, so we still didn't reach that point yet (I skipped throught the book and saw what you mentioned). I changed all "char *" into "string" and it worked, but I had to #include <string> in the header file, is this good practice? And could you explain what you meant by "I would usually return const std::string& " ? Does that mean that "string personName" should be declared as a const? One more thing, if I'm using strings now, then shall I use the cin.getline() function or is it enough to use "cin >> name" for example without specifying a limit?

    Thanks

    Edit: how can I keep spaces in a string when input from a user? cin won't work and neither does cin.getline().
    Last edited by Azimuth; 06-11-2004 at 01:06 PM.

  13. #13
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    There is a separate getline for strings. Instead of:
    Code:
    std::cin.getline(myCharArray);
    its
    Code:
    std::getline(std::cin, myString);
    Note that since you are using VC++ 6.0, you might have an issue with getline with strings. Go to http://www.dinkumware.com/vc_fixes.html and scroll down to the part about <string>.

    As far as returning a string, you can return a const std::string& or just a string. The second one makes a copy, which is easier if you have no performance concerns (and often even if you do). Including <string> in the header file is fine if you need it there - which you will if you have string members. I would suggest typing std::string, though, especially in your header files, instead of using a using directive.

  14. #14
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    I'm currently doing a summer session in university and I'm taking a course called "Introduction to computer science II" which deals with OOP, so we still didn't reach that point yet (I skipped throught the book and saw what you mentioned). I changed all "char *" into "string" and it worked, but I had to #include <string> in the header file, is this good practice?
    Yes, make sure you don't do #include <string.h> which will just include the c string library. If you need to use the c string library do #include <cstring>

    And could you explain what you meant by "I would usually return const std::string& " ?
    In this case, I would say that performance does matter. const std::string& is just as clear as returning std::string, and it avoids copying two string objects and the dynamic memory allocation that goes with it. Code that is written to copy will also work. For instance, you can write code like

    Code:
    const std::string& s =   computer.getPersonName()
    and this will avoid the copy. On the other, code like that copies
    Code:
    std::string s;
    s = computer.getPersonName();
    will also work. Of course, you would also want to inline these one-line functions if your not likely to change them.

    Does that mean that "string personName" should be declared as a const?
    No, you will want to be able to change personName.

  15. #15
    Registered User
    Join Date
    Jun 2004
    Posts
    9
    Ok, so this is what I changed:

    Code:
    // In the class definition
    	string getPersonName();
    
    // into
    
    	const string& getPersonName();
    
    // and in the implementation
    
    string Computer::getPersonName()
    {
    	return personName;
    }
    
    // into
    
    const string& Computer::getPersonName()
    {
    	return personName;
    }
    Isn't that what you guys meant? What is the significance of using 'const' ? I tried applying this method to the setPersonName() function as well, so it became:

    Code:
    void setPersonName(const string& name)  {
    	personName = name;
    }
    So can't this be extended to every other function regardless of the parameter type it requires or returns (int, char, string, struct, class, etc...). It seems that this may be beneficial when passing and returning large objects instead of making a copy of them, so why are we applying it to strings if they usually don't take up a lot of space?

    Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Some questions with strings, vectors, references...
    By samus250 in forum C++ Programming
    Replies: 11
    Last Post: 07-10-2008, 02:31 PM
  2. Couple of Questions
    By toonlover in forum Windows Programming
    Replies: 10
    Last Post: 07-14-2006, 01:04 AM
  3. Need help with using strings in classes
    By orikon in forum C++ Programming
    Replies: 5
    Last Post: 11-12-2005, 03:01 PM
  4. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  5. Help with classes & strings members
    By GrNxxDaY in forum C++ Programming
    Replies: 7
    Last Post: 07-21-2002, 08:29 PM