473,387 Members | 1,650 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

String Class Constructors

Our assignment calls for us to create a user defined string class, without using anything from the directories string.h, string, or cstring.

however in the implementation file we're given, there are two different forms of the constructor.

Expand|Select|Wrap|Line Numbers
  1.  String(const string&); 
and
Expand|Select|Wrap|Line Numbers
  1. String(const char[ ] ); 
The variables are as follows.
Expand|Select|Wrap|Line Numbers
  1. unsigned Length;
  2. unsigned Capacity;
  3. char * Mem;
  4.  
I have a general idea about the string& constructor, though I'm not sure how to apply the c-type data.

Expand|Select|Wrap|Line Numbers
  1. String::String(const string& RHS )
  2. {
  3.   Length = RHS.Length;
  4.   Capacity = RHS.Capacity;
  5.   Mem = RHS;
  6. }
  7.  
but I know that's not right, namely the Mem part.

the const char [] constructor is really where I have no clue, since I'm not sure how to check the length of the data being inserted into the array, namely, how to set Length.

Also, How does the program differentiate between the two constructors? what If I were to compare two different 'strings' and wanted to use the c-type array?

Help is greatly appreciated.
Mar 19 '08 #1
15 2073
Laharl
849 Expert 512MB
A C-string is ended by a terminating null character, '\0'. The ASCII code for this special character is 0. The program (meaning the compiler) can tell the difference between the constructors because the parameters are different.

To compare two different strings, you first need to see if they are the same length. Then you can check if all the characters are the same.
Mar 19 '08 #2
but how exactly does the code for the inside of each constructor go? How close am I on understanding the first constructor?

I'm still unsure on how to construct the c-type.
something like
Expand|Select|Wrap|Line Numbers
  1.  x = [hello world];
  2. A = new String(x);
  3.  
but what exactly goes into the constructor to achieve this? I'm unsure on what to do or how to get it to work.
Mar 19 '08 #3
alright, update on my constructors...The first one (copy existing String) looks okay, but I'm still unsure on the C-style constructor.

Expand|Select|Wrap|Line Numbers
  1. String::String(const String& RHS)
  2. {
  3.     Length = RHS.Length;
  4.     Capacity = RHS.Capacity;
  5.     Mem = new char[Length+1];
  6.  
  7.     for (unsigned i = 0; i < Length ; i++ )
  8.     {
  9.         Mem[i] = RHS[i];
  10.     }
  11.  
  12.     Mem[Length] = "\0";
  13. }
  14.  
Here's the other one I'm not sure on
Expand|Select|Wrap|Line Numbers
  1. String::String(const char[] str)
  2. {
  3.     Mem = [str];
  4.     Length = str.Length();
  5.     Capacity = str.Capacity();
  6. }
  7.  
How close is this to the proper way of constructing the objects? is there a way to test just these constructors to see if they work?
Mar 19 '08 #4
oler1s
671 Expert 512MB
If you want to see if the code you wrote works, why don't you try it out in a compiler? Sometimes, experimentation is a great way to learn. No one is born enlightened. Besides, it's pure silly if you start writing large blocks of code without checking with a compiler.

You may want to learn about initializer lists. They'll come in handy for the String& constructor. What about Length? If I gave you a String&, and asked you to tell me the length, how would it work? Finally, there's a critical difference between "\0" and '\0'. The type of quotes do have a meaning. The mistake you made should actually fail on compilation.

Your constructor that works with C strings is a pure mess, however. Fundamentally, you seem to lack proper understanding of what a C string is. A Cstring is an array of characters. With the one special property that it is terminated by the \0 character at the end of the other characters. A Cstring is not a first class citizen in C or C++. It does not have any special properties. It does not undergo special code. So you can't do something with a C string that wouldn't make any sense with a normal array. That means, you can do Length(), you can't do Capacity(), and [str] makes absolutely no sense.

Cstrings are tricky. But they are at heart, simple arrays. So you need to understand how arrays work, really really well. If you are having trouble converting logic into code, ask here. But don't guess at the code.
Mar 19 '08 #5
yeah, things start to clear up when you get a good night's sleep.

okay, so with the c-style string, I'm passing in an array. Since we're not allowed to use strlen, I'm going to have to loop down that array, counting each character, until I hit the \0.

Expand|Select|Wrap|Line Numbers
  1. int num = 0, lenCount = 0;
  2. while ( str[num] != '\0' )
  3. {
  4.   lenCount += 1;
  5.   num++;
  6. }
  7.  
then I'm going to have to create a new buffer to place this array in, yes?
Expand|Select|Wrap|Line Numbers
  1. Mem = new char[lenCount];
  2.  
then fill it, much like the copy constructor does.

Now the logic that I'm still not quite getting is the capacity. Would I set it initially to the value of Length? when I do need to increase it, isn't it increased by a number of 16? and yes, I do know that capacity cannot be less than the length.

The reason I'm asking about capacity is because we need to create an append (+=) operator, though I don't know how exactly I'd increase the capacity in my code.

As for testing, if A was an string of array [Hello World], would cout << A give me hello world, or do I need to build the << overload before testing?

Thanks again for your help.
Mar 19 '08 #6
Laharl
849 Expert 512MB
I'm not quite sure what you mean about 'a string with array [Hello World]', but you probably need to overload it either way.

Capacity should be initially set to the value of length, I guess, as long as you update it every time you need to increase the size.

Also, you'll need to add one to lenCount, since the code as written doesn't include the null terminator. You also need to include space for said null terminator in the new array, so take that into consideration.
Mar 19 '08 #7
when capacity is increased, would I create a new spot in memory that's of longer length? or can the original one be updated?

so if I had a String that contained 'hello' and one that contained 'world', could I update 'hello's capacity to something like 16 and then add 'world'?

logically I just don't see how updating the capacity variable creates more memory in that array.
Mar 19 '08 #8
oler1s
671 Expert 512MB
okay, so with the c-style string, I'm passing in an array. Since we're not allowed to use strlen, I'm going to have to loop down that array, counting each character, until I hit the \0.
Precisely. Although in your code, your use of both num and lenCount is redundant.

then I'm going to have to create a new buffer to place this array in, yes?...then fill it, much like the copy constructor does.
Correct. But be careful about the size of the array. Use examples to determine if you have off by one errors and what not. If I have the array H E L L O \0 , what does lenCount give me? Don't assume. Walk through the loop as many times as it takes, and write down the values of num vs. lenCount. What do you get? And how big does your new array have to be? (By asking this question, I think you have an off by one error).

Now the logic that I'm still not quite getting is the capacity. Would I set it initially to the value of Length?
Depends on how you define Length.

when I do need to increase it, isn't it increased by a number of 16?
By what logic?

The reason I'm asking about capacity is because we need to create an append (+=) operator, though I don't know how exactly I'd increase the capacity in my code.
Sit and think about it for a while. String concatenation and appending is a real problem in programming. Come up with some ideas, and think about how efficient they are. And yes, depending on how it's implemented, string appending can be really, really inefficient.

As for testing, if A was an string of array [Hello World], would cout << A give me hello world, or do I need to build the << overload before testing?
As in, if you were to try to pass your string class to the << operator, would it automatically print out the contents? No way. You have to deal with the overload yourself. There's a few traps in doing this, so for testing purposes, you may want to put a quick hack of a debug function in your code. Once you get everything else working, we can help you tackle the ostream overload.
Mar 19 '08 #9
alright, here's what i've been thinking on for the += operator.

Expand|Select|Wrap|Line Numbers
  1.    void String::operator+=(const String& rhs)
  2.    {
  3.       unsigned short rhsLen = rhs.Length;
  4.       unsigned short totalLen = Length + rhsLen;
  5.       String  temp(totalLen);
  6.       for (unsigned short i = 0; i<Length; i++)
  7.          temp[i] = Mem[i];
  8.       for (unsigned short j = 0; j<rhs.Length; j++, i++)
  9.          temp[i] = rhs[i-Length];
  10.       temp[totalLen]='\0';
  11.       *this = temp;
  12.    }
  13.  
Though this way doesn't deal with the capacity of the memory, since a new String is created.

As for what 'capacity' is defined as in our program, this was what it says.
" The length of a data object of type "String" is the number of characters
that it contains; the capacity is the number of bytes of memory which have
been allocated to hold those characters. The capacity is always a multiple
of 16 bytes, and is always greater than or equal to the length."

I don't know if that helps, or if it changes the design of my operator.
Mar 19 '08 #10
so instead of creating a new String object every time the += operator is called, wouldn't this work better and more efficient?

Expand|Select|Wrap|Line Numbers
  1. String& String::operator+= (const String& rhs)
  2. {
  3.   unsigned totalLen = rhs.Length + Length;
  4.   if (totalLen < Capacity)
  5.     {
  6.       //fill the Mem[] with the rhs String
  7.     }
  8.   else
  9.   {
  10.     Capacity = totalLen; //or Capacity = Capacity*2, just something that
  11.     //fill the Mem[] with the rhs String once Capacity has been increased
  12.   }
  13.   return *this;
  14. }
  15.  
also, I'm still not sure on how to print these variables to test the constructor/operator without already having the << overloaded. is there some sort of code availiable?
Mar 19 '08 #11
Laharl
849 Expert 512MB
You can print the integers with no trouble, though the C-string will require a loop to print each character. Printing the class as a whole, though, (aka passing a string object to <<), will require the overload function to be written.

Your append code is a good start, I think.
Mar 19 '08 #12
I'm getting some errors on testing the constructors. I've built a small main program to print out these Strings, though I have some errors that don't make sense to me

proj07.main.cpp:9: error: new types may not be defined in a return type
proj07.main.cpp:9: error: extraneous `int' ignored
proj07.main.cpp:9: error: `main' must return `int'

proj07.string.cpp:14: error: new types may not be defined in a return type
proj07.string.cpp:14: error: return type specification for destructor invalid
In file included from proj07.main.cpp:6:

Explanations are fine, and if you need the code to see, let me know
Mar 20 '08 #13
Laharl
849 Expert 512MB
Destructors, like constructors, return nothing. Not void, nothing. Main has to return an int, conventionally zero for a successful run. That's about all I can give you without seeing code.
Mar 20 '08 #14
If i have the implementation file and source file separate, how do i pass around the private variables? I know that private variables are limited to the class itself, but isn't the source code file implementing part of the class?
Mar 20 '08 #15
Laharl
849 Expert 512MB
If you declare the private variables in the .h, and then #include the .h in your .cpp, you can use the private variables without issues in your function implementations.
Mar 20 '08 #16

Sign in to post your reply or Sign up for a free account.

Similar topics

50
by: Dan Perl | last post by:
There is something with initializing mutable class attributes that I am struggling with. I'll use an example to explain: class Father: attr1=None # this is OK attr2= # this is wrong...
2
by: JohnnySparkles | last post by:
Hi everyone, I'm currently writing an application which uses the XmlSerializer class to serialize/deserialize objects to/from xml. Now when deserializing an XmlDocument back into the object,...
2
by: Andrew | last post by:
I have written two classes : a String Class based on the book " C++ in 21 days " and a GenericIpClass listed below : file GenericStringClass.h // Generic String class
5
by: Bernhard Hidding | last post by:
Hello, I want to combine a string with an integer. I work on SuSE 9.1 with g++. Why does this piece of code not work? #include <iostream.h> #include <stdio.h> #include <fstream.h> #include...
3
by: matthurne | last post by:
I'm doing a chapter 12 exercise from Accelerated C++ ... writing a string-like class which stores its data in a low-level way. My class, called Str, uses a char array and length variable. I've...
6
by: Fred | last post by:
Hi I have a class defined in a library that I'd like to add some extra functionality to. This will involve adding a few member variables and a few related methods. As I understand it I can...
3
by: bob | last post by:
Hi, I'm looking at a legacy string class thats been in use here for a while and I'd like to check out any options available to optimise it. I see a couple of constructors that look dubious....
8
by: Paul Craig | last post by:
Hi, I am currently able to open forms given a string variable using the following code: Dim strForm As String = "Form1" Dim theForm As Form theForm =...
84
by: Peter Olcott | last post by:
Is there anyway of doing this besides making my own string from scratch? union AnyType { std::string String; double Number; };
7
by: dragoncoder | last post by:
Hello experts, I have the following code me. =cat mystring.h #include<iostream> using namespace std; class mystring {
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.