0
I Use This!
Activity Not Available

Project Summary

code, wiki, downloads and so on.

Exercises:

Exercise 12.18: Explain the following code. Indicate which definition of Type or initVal is used for each use of

those names. If there are any errors, say how you would fix the program.

typedef string Type;

Type initVal();

class Exercise {

public:

// ...

typedef double Type;

Type setVal(Type);

Type initVal();

private:

int val;

};

Type Exercise::setVal(Type parm) {

val = parm + initVal();

}The definition of the member function setVal is in error. Apply the necessary changes so that the class Exercise

uses the global typedef Type and the global function initVal.

Answer 12.18: This code starts by defining a global typedef named Type as a synonym for string. The

declaration initVal uses this typedef, meaning that the function returns a string. The class Exercise

defines its own member named Type that is also a type name. Inside Exercise, the name Type is a

synonym for double. The Exercise members, setVal and initVal are defined after the definition of

Type. Their return types, therefore, refer to the name Type as defined inside the Exercise class. These

functions return double.

The definition of Exercise::setVal is in error because the return type in the definition does not

match the return type used in the declaration of the function inside Exercise. The definition uses the

global typedef, whereas the declaration used the definition of Type that is a member of the Exercise

class.

typedef string Type;

Type initVal(); // uses the global definition of Type; initVal returns a string

class Exercise {

public:

// ...

typedef double Type; // hides the global definition of Type

::Type setVal(::Type); // uses global definition of Type

::Type initVal(); // uses global definition of Type

private:

int val;

};

// Changed so that the parameter and return type refer to the global definition of Type.

::Type Exercise::setVal(::Type parm) {

val = parm + ::initVal(); // calls global definition of initVal

}

Exercise 12.19: Provide one or more constructors that allows the user of this class to specify initial values for none

or all of the data elements of this class:

class NoName {

public:

// constructor(s) go here ...

private:

std::string pstring;

int ival;

double dval;

};

Explain how you decided how many constructors were needed and what parameters they should take.

Answer 12.19: The class as presented gives no obvious guidance on which member values the user should

be allowed to provide and which should be set by default. Hence, we define the entire set of combinations,

allowing the user to selectively define zero or more of the members:

#include

class NoName {

public:

// constructors: all data members are built-in types and must be explicitly initialized

// default constructor, takes no arguments

NoName(): pstring(0), ival(0), dval(0) { }

// constructor to initialize the pointer member

NoName(std::string p): pstring(p), ival(0), dval(0) { }

// constructor to initailize the int member

NoName(int i): pstring(0), ival(i), dval(0) { }

// constructor to initialize the double member

NoName(double d): pstring(0), ival(0), dval(d) { }

// constructor to initialize the int and double members

NoName(int i, double d): pstring(0), ival(i), dval(d) { }

// constructor to initialize the pointer and int members

NoName(std::string p, int i): pstring(p), ival(i), dval(0) { }

// constructor to initialize the pointer and double members

NoName(std::string p, double d): pstring(p), ival(0), dval(d) { }

// constructor to initialize all three members

NoName(std::string p, int i, double d): pstring(p), ival(i), dval(d) { }

private:

std::string pstring;

int ival;

double dval;

};

Exercise 12.23: Assume we have a class named NoDefault that has a constructor that takes an int but no default

constructor. Define a class C that has a member of type NoDefault. Define the default constructor for C.

Answer 12.23:

#include

class NoDefault {

public:

NoDefault(int);

// additional members follow, but no other constructors

};

class C {

NoDefault ND_member; // NoDefault requires an int initializer

std::string illustration; // for illustration purposes

// other members of C

public:

C(): ND_member(0) { } // we must explicitly initialize ND_member

// ok to implicitly initialize illustration

// remaining members of C

};

Exercise 12.27: Which, if any, of the following statements are untrue? Why?

(a) A class must provide at least one constructor.

(b) A default constructor is a constructor with no parameters for its parameter list.

(c) If there are no meaningful default values for a class, the class should not provide a default constructor.

(d) If a class does not define a default constructor, the compiler generates one automatically, initializing each data

member to the default value of its associated type.

Answer 12.27:

(a) False—a class is not required to define any constructors.

(b) False—The default constructor must be callable with no arguments; the constructor may have multiple

parameters so long as they each have a default argument.

(c) Depends—Classes that do not define a default constructor have limitations that can be problematic.

It is usually a good idea to define a default constructor even when nonobvious initial values must

be invented to use to initialize the data members. However, in some cases the difficulty of defining

appropriate defaults can outweigh the limitations of not having a default constructor. So, although

most classes ordinarily ought to have a default constructor, it is possible for perfectly good reasons to

define a class that does not have a default constructor.

(d) False—The compiler synthesizes the default constructor only if a class defines no other constructors.

Also, the synthesized constructor uses the same rules as variable initialization: Members of class type

are guaranteed to be initialized by running the member’s own default constructor. Members of built-in

type are initialized only for non-static objects. The built-in members of local nonstatic objects of the

class type are uninitialized.

Exercise 12.29: Explain what operations happen during the following definitions:

string null_isbn = "9-999-99999-9";

Sales_item null1(null_isbn);

Sales_item null("9-999-99999-9");

Answer 12.29:

null_isbn is initialized by first constructing a temporary using the string constructor that takes

a const char. That temporary is then copied into null_isbn using the string constructor that

takes a reference to a const string.

null1 is constructed using the Sales_item constructor that takes a string.

null is constructed by first using the string constructor that takes a const char to create a

temporary string and then passing that temporary to the Sales_item constructor that takes a

string.

Exercise 12.42: Which, if any, of the following static data member declarations and definitions are errors? Explain

why.

// example.h

class Example {

public:

static double rate = 6.5;

static const int vecSize = 20;

};

// example.C

#include "example.h"

double Example::rate;

Answer 12.42:

• The declaration of rate is in error because only const integral static members may be initialized in

the class body.

• The declaration of vecSize is fine. This member is a static that has a const integral type, which

means that it can be initialized inside the class body.

• The definitions of rate is ok. The rate member is value initialized, meaning that it

is set to zero.

Exercise 13.5: Which class definition is likely to need a copy constructor?

(a) A Point3w class containing four float members

(b) A Matrix class in which the actual matrix is allocated dynamically within the constructor and is deleted within

its destructor

(c) A Payroll class in which each object is provided with a unique ID

(d) A Word class containing a string and a vector of line and column location pairs

Answer 13.5:

(a) The synthesized copy constructor is likely to work fine for the Point3w class.

(b) The Matrix class needs a copy constructor to make a copy of the dynamically allocated storage. Because

the destructor destroys the matrix, each Matrix object needs its own copy.

(c) Whether the Payroll class needs a copy constructor depends on the detailed design of this class. It

is possible that we should not be allowed to copy Payroll objects. Alternatively, it is possible that

copying a Payroll should copy all the corresponding information. That is, copying an object should

not generate a new ID, but should copy the existing ID. In the first case, we would make the copy

constructor private in order to prevent copies. In the second, we could use the default copy constructor,

which would copy the ID.

(d) The Word class probably can use the synthesized constructor. That constructor will delegate to the

string and vector classes the job of copying the member data.

Exercise 1.17: Write a program to ask the user to enter a series of numbers. Print a message saying how many of

the numbers are negative numbers.

Answer 1.17:

#include

int main()

{

std::cout << "Enter a series of numbers" << std::endl;

int i;

int ctr = 0;

while (std::cin >> i)

if (i < 0)

++ctr;

std::cout << ctr << " numbers were negative" << std::endl;

return 0;

}

Exercises Section 1.4.4

Exercise 1.19: What happens if you give the numbers 1000 and 2000 to the program written for the previous exercise?

Revise the program so that it never prints more than 10 numbers per line.

Answer 1.19: What happens when the input values are 1000 and 2000 depends on the details of the program’s

print statement. The program might well have printed all its output to a single line in which case

the output line would be enormous—it would print the thousand values from 1000 up to 2000. If it printed

a single number to each line, then the output would consume 1000 lines.

We could force the program to print 10 values to a line as follows:

#include

int main()

{

std::cout << "Enter two numbers:" << std::endl;

int v1, v2;

std::cin >> v1 >> v2; // read input

// use smaller number as lower bound for printing the range

// and larger number as upper bound

int lower, upper;

if (v1 <= v2) {

lower = v1;

upper = v2;

} else {

lower = v2;

upper = v1;

}

// print values fromlower up to and but not including upper

int newline_ctr = 0;

for (int val = lower; val != upper; ++val) {

std::cout << val << " ";

++newline_ctr; // increment counter to indicate another value printed

if (newline_ctr == 10) { // if we’ve already printed 10 values

std::cout << std::endl; // print this line

newline_ctr = 0; // and reset the counter to 0

}

}

std::cout << std::endl;

return 0;

}

Exercise 2.19: What is the value of j in the following program?

int i = 42;

int main()

{

int i = 100;

int j = i;

// . . .

}

Answer 2.19: The value of j is 100. The outer variable named i is hidden by the local variable with the

same name.

Exercise 2.19: What is the value of j in the following program?

int i = 42;

int main()

{

int i = 100;

int j = i;

// . . .

}

Answer 2.19: The value of j is 100. The outer variable named i is hidden by the local variable with the

same name.

Exercise 2.32: Which of the following declarations and definitions would you put in a header? In a source file?

Explain why.

(a) int var;

(b) const double pi = 3.1416;

(c) extern int total = 255;

(d) const double sq2 = sqrt(2.0);

Answer 2.32:

(a) This statement defines var and so most probably belongs in a source file, not a header.

(b) const variables that are initialized to a constant value ordinarily should go in header files. When we

put definitions such as this one in a header, each file that includes the header will have its own copy of

pi. By putting the definition in a header we give the compiler access to the value of the initializer in

each file.

(c) Despite the extern keyword, this statement is a definition because the variable is initialized. Definitions

ordinarily go in source files, not headers.

(d) Because the initializer is not itself a constant, there is no reason to put the initialization in a header file.

However, we might still want to make the initialized const value available across multiple files. The

way to do so would be to put an extern declaration for sq2 into a header and put the definition of

sq2 in one of the source files that includes that header:

extern const double sq2; // this declaration goes in a header

extern const double sq2 = sqrt(2.0); // the definition goes in a source file

Exercise 4.12: Given a pointer, p, can you determine whether p points to a valid object? If so, how? If not, why

not?

Answer 4.12: No, it is not possible to know whether a given pointer holds the address of an object. At

best, we can know only whether the pointer holds 0, indicating that it does not point at any object.

Exercise 4.13: Why is the first pointer initialization legal and the second illegal?

int i = 42;

void p = &i;

long lp = &i;

Answer 4.13: Both initializations initialize the pointer from an address. In general, a pointer may be initialized

or assigned only from the address of an object of the same type as the pointer.

The exception is type void. A void pointer may hold the address of any nonconst object.

A pointer to long may only hold the address of a long object; the second initialization attempts to

initialize a pointer to long from the address of an int.

Exercise 4.16: What does the following program do?

int i = 42, j = 1024;

int p1 = &i, p2 = &j;

p2 = p1 p2;

p1 = p1;

Answer 4.16:

The first statement defines and initailizes two int variables.

The second defines and initailizes two pointers that point to these variables.

Assuming this program runs on a machine with ints that are larger than 16 bits, the third statement

assigns the value 43008 (which is 42 1024) to j. It executes as follows:

• Dereference p1 and p2, which fetches the current values in i and j, respectively.

• Multiply the values of i and j.

• Dereference p2 in order to assign to it. This statement is effectively the same as j = i j.

The final statement assigns the value 1764 (42 42) to i:

• The = operator multiplies the left-hand operand by the right-hand operand, storing the result in the

left-hand operand.

• The left- and right-hand operands each dereference p1, which fetches i. The value currently in i is

42.

Exercise 4.23: What does the following program do?

const char ca[] = {’h’, ’e’, ’l’, ’l’, ’o’};

const char cp = ca;

while (cp) {

cout << cp << endl;

++cp;

}

Answer 4.23: The behavior of this program is undefined. The loop that reads through cp assumes that cp

points to a null-terminated character array. However, cp actually point to ca, which is not null-terminated.

Although the behavior of this program is undefined, many compilers will generate code that when

executed will read memory starting from ca0 until a null character is found.

Another exercise:

This code is wrong:

/...../ TCHAR msg24MAX_PATH func(msg); /...../

func(TCHAR pmsg24MAX_PATH) { TCHAR m_pmesg; m_pmesg = pmsg; }

It generates the error

error C2440: '=' : cannot convert from 'TCHAR []2260' to 'TCHAR 42260'

on the line 'm_pmesg = pmsg' as well as 'func(msg)'.

Solution:

ou ca do either:

func(TCHAR pmsg24MAX_PATH)

or func(TCHAR pmsg[]4MAX_PATH)

this is because an array becomes a pointer when it is passed to a function. Arrays are never passed by value (unless they are in a struct or class).

e.g.

void func( char i[] ); // (essentially the same as func( char i ) ) char v30;

func( v );

m_pmesg is a pointer to a element of the array but you're trying to assign it a pointer to the entire array. Hence you get the message of type mismatch.

const int MAX_PATH = 200;

char msg24MAX_PATH;

void func(char pmsg24MAX_PATH) { char m_pmesg; m_pmesg = pmsg00; }

int main() { func( msg ); }

Another one:

int q32 = { {1},{2},{3} };

int r = &q00; // pointer to run through q[][] element-by-elememt

int s = r + sizeof(q)/sizeof(int); // just past end of q[][]

for ( ; r < s; ++r)

cout << r << ' ';

what is the ouput?:

1 0 2 0 3 0

And test this example:

#include

int main(int argc, char argv[])

{

cout << "# of arguments is "<< argc-1 <<'\n';
cout << "program name is "<< argv0 <<'\n';
cout << "first letter of prog name is '"<<<"'\n";
char argv_copy = argv;
while (argc--)
cout << ++argv<<'\n';
cout << "print arguments again:\n";
while (++argv_copy)
cout << argv_copy <<'\n';
}

Tags

No tags have been added

In a Nutshell, ottawacplusplus...

 No code available to analyze

Open Hub computes statistics on FOSS projects by examining source code and commit history in source code management systems. This project has no code locations, and so Open Hub cannot perform this analysis

Is this project's source code hosted in a publicly available repository? Do you know the URL? If you do, click the button below and tell us so that Open Hub can generate statistics! It's fast and easy - try it and see!

Add a code location

GNU General Public License v2.0 or later
Permitted

Commercial Use

Modify

Distribute

Place Warranty

Forbidden

Sub-License

Hold Liable

Required

Include Copyright

Include License

Distribute Original

Disclose Source

State Changes

These details are provided for information only. No information here is legal advice and should not be used as such.

All Licenses

This Project has No vulnerabilities Reported Against it

Did You Know...

  • ...
    Black Duck offers a free trial so you can discover if there are open source vulnerabilities in your code
  • ...
    check out hot projects on the Open Hub
  • ...
    in 2016, 47% of companies did not have formal process in place to track OS code
  • ...
    learn about Open Hub updates and features on the Open Hub blog

 No code available to analyze

Open Hub computes statistics on FOSS projects by examining source code and commit history in source code management systems. This project has no code locations, and so Open Hub cannot perform this analysis

Is this project's source code hosted in a publicly available repository? Do you know the URL? If you do, click the button below and tell us so that Open Hub can generate statistics! It's fast and easy - try it and see!

Add a code location

Community Rating

Be the first to rate this project
Click to add your rating
   Spinner
Review this Project!
Sample ohloh analysis