Repetitive Code within Multiple Functions

Is it better to place all repetitive code used by multiple functions into its own separate function? For example, in a string class you would have the constructors use a for loop to count the number of elements in the input string to determine how big to make the classes' strPtr member variable. So would it be best to just write the same for loop in each constructor or make a function called inputLength() (setLength is already used to update the str_len member variable)?

1
2
3
4
5
6
7
8
9
10
11
12
class String
{
public:
     String( const char *, int start, int count );
     String( const String &, int start, int count );
private:
     void setLength( unsigned int );     // sets str_len
     void inputLength(  unsigned int );  // determines input string's length

     char *strPtr;                    // pointer used for dynamic memory allocation
     unsigned int str_len;       // size used when allocating memory for strPtr
}


or would that start to complicate the class definition with a large number of similarly sounding private functions?
Last edited on
Why exactly do you have setLength/inputLength...? If all it does is set str_len, there is no point in having it...str_len should be managed by internal functions only, and the user should only be able to see it.
I don't understand exactly what you mean.

str_len is a private member variable that determines the length ( or size ) needed when dynamically allocating memory for strPtr:

 
char *strPtr = new char[str_len];


and being a private member variable, it will only be updated by member functions and not directly by the user (which is why they are private).

inputLength member function, on the other hand, is used to determine the length of the string passed to the constructors ( or any function that takes a String string or const char * ) in which to figure out how much length is needed to add to str_len when resizing, prepending, removing, etc.

1
2
3
4
5
bool String::prepend( const char * string )
{
     unsigned int length = inputLength( string );     // how many characters are in string
     setLength( str_len + length );                   // str_len += length
}


...rather than having to rewrite the same for loop for each function that needs to determine the input string's length...

1
2
3
4
5
6
7
8
9
bool String::prepend( const char * string )
{
     unsigned int length;

     for ( int index = 0; string[index] != NULL; index++ )
          length = index + 2;     // plus one for NULL and plus one due to ZERO indexing

     setLength( str_len + length );
}


Although, now that I think about it, inputLength should probably return an unsigned int value in which to pass to setLength ( as shown in the previous example )...

 
unsigned int inputLength( unsigned int );


And wouldn't that make setLength and inputLength "internal functions"?
Last edited on
Ok...this is how I would rewrite your function:

1
2
3
4
5
bool String::prepend( const char * string )
{
     unsigned int length = strlen( string );     //strlen is already provided for you
     this->str_len += length;                     // don't need to use a function, you have access to the variables in your class
}


You don't need to functions to set your private variables, your class functions have access to them.
String::str_len is just an integer. The "same code in every function that takes a string" will just be this->str_len=something. That's not reason enough to add another function. You're just adding more bureaucracy your own functions will have to go through.

Interfaces are good (mostly) when they're for the user. You're not a user.

There's also a limit to how much you should... "functionalize". A whole function for a single assignment is just not worth it (unless the function is an interface). It's good to avoid code repetition, but that's just ridiculous.

a for loop to count the number of elements in the input string to determine how big
See strlen() defined in cstring.
Last edited on
Ok thanks, I know about strlen() but am attempting to not rely on other libraries ( except iostream ) because I'm doing my own string class for learning purposes and prefer to do the task that the c-string library provides ( another class I wish to impliment for learning purposes as well ) manually.

Basically the question was, "when was it preferable to functionalize repetitive code?" and now I have the answer =). However, the answer could have been answered without nit picking the example. The example was given to demonstrate the point of the question, not to be corrected. lol
Last edited on
Topic archived. No new replies allowed.