Please explain what is meant by:
When you need an object to live beyond the current scope |
Well, let's say you wanted to create a c-style string holding the binary representation of a number:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
#include <iostream>
#include <limits>
#include <cstdlib>
void printBinaryString(unsigned) ;
int main()
{
unsigned num ;
std::cout << "Enter non-numeric input to quit.\n" ;
while ( (std::cout << "Enter a number: ") && (std::cin >> num) )
printBinaryString(num) ;
}
void printBinaryString(unsigned num)
{
const int binaryRadix = 2 ;
char str[std::numeric_limits<unsigned>::digits+1] = {0} ;
itoa(num,str,binaryRadix) ;
std::cout << str << '\n' ;
}
|
Everything is all well and good here, but suppose we want to divorce the printing of the string from generation of the string representation? That means that the program needs a little restructuring. We can probably begin with a new name and prototype for generating the string:
char* toBinaryString(unsigned num)
and if we go for a straightforward conversion of the code we might come up with:
1 2 3 4 5 6 7 8
|
char* toBinaryString(unsigned num)
{
const int binaryRadix = 2 ;
char str[std::numeric_limits<unsigned>::digits+1] = {0} ;
itoa(num,str,binaryRadix) ;
return str ;
}
|
but we come up against a problem here.
str only exists inside of
toBinaryString. When
toBinaryString returns, the memory occupied by
str is reclaimed. One way to get around this is to use dynamic memory, giving us a program that looks like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include <iostream>
#include <limits>
#include <cstdlib>
char* toBinaryString(unsigned) ;
int main()
{
unsigned num ;
std::cout << "Enter non-numeric input to quit.\n" ;
while ( (std::cout << "Enter a number: ") && (std::cin >> num) )
{
char* s = toBinaryString(num) ;
std::cout << s << '\n' ;
delete [] s ;
}
}
char* toBinaryString(unsigned num)
{
const int binaryRadix = 2 ;
char* str = new char[std::numeric_limits<unsigned>::digits+1] ;
itoa(num,str,binaryRadix) ;
return str ;
}
|
Now, you can probably tell this example is a bit contrived (we may have wanted to store those strings to manipulate them later, for instance.) There are better ways to do this in both C and C++. In C++ using std::string (which manages dynamic memory internally so you don't have to) would be appropriate, but hopefully it illustrates the lifetime issue for you.