double
double
illegal–cannot use struct
tag instead of a structure variable
illegal–savingsAccount
undeclared
char
TermAccount
A $9.99
A $1.11
3. Many compilers give poor error messages. Surprisingly, the error message from g++
is quite informative.
g++ -fsyntax-only c10testq3.cpp
c10testq3.cc:8: semicolon missing after declaration of
'Stuff'
c10testq3.cc:8: extraneous 'int' ignored
c10testq3.cc:8: semicolon missing after declaration of
'struct Stuff'
4. A x = {1,2};
Too few initializers, not a syntax error. After initialization, dueDate.month == 12
, dueDate.day == 21
, dueDate.year == 0
. Member variables not provided an initializer are initialized to a zero of appropriate type.
Correct after initialization: 12 == dueDate.month
, 21 == dueDate.day
, 2022 == dueDate.year
.
Error: too many initializers.
May be a design error, that is, an error in intent. The author of the code provides only two digits for the date initializer. There should be four digits used for the year because a program using two-digit dates could fail in ways that vary from amusing to disastrous at the turn of the century.
struct EmployeeRecord
{
double wageRate;
int vacation;
char status;
};
void readShoeRecord(ShoeType& newShoe)
{
cout << "Enter shoe style (one letter): ";
cin >> newShoe.style;
cout << "Enter shoe price $";
cin >> newShoe.price;
}
ShoeType discount(ShoeType oldRecord)
{
ShoeType temp;
temp.style = oldRecord.style;
temp.price = 0.90 * oldRecord.price;
return temp;
}
struct StockRecord
{
ShoeType shoeInfo;
Date arrivalDate;
};
StockRecord aRecord;
aRecord.arrivalDate.year = 2006;
void DayOfYear::input()
{
cout << "Enter month as a number: ";
cin >> month;
cout << "Enter the day of the month: ";
cin >> day;
}
void Temperature::set(double newDegrees, char newScale)
{
degrees = newDegrees;
scale = newScale;
}
13. Both the dot operator and the scope resolution operator are used with member names to specify the class
or struct
of which the member name is a member. If class DayOfYear
is as defined in Display 10.3 and today
is an object of the class DayOfYear
, then the member month
may be accessed with the dot operator: today.month
. When we give the definition of a member function, the scope resolution operator is used to tell the compiler that this function is the one declared in the class whose name is given before the scope resolution operator.
void DayOfYear::checkDate( )
{
if ((month < 1) || (month > 12)
|| (day < 1) || (day > 31))
{
cout << "Illegal date. Aborting program.\n";
exit(1);
}
if (((month == 4) || (month == 6) || (month == 9)
|| (month == 11))
&& (day == 31))
{
cout << "Illegal date. Aborting program.\n";
exit(1);
}
if ((month == 2) && (day > 29))
{
cout << "Illegal date. Aborting program.\n";
exit(1);
}
}
hyundai.price = 4999.99; //ILLEGAL. price is private.
jaguar.setPrice(30000.97); //LEGAL
double aPrice, aProfit; //LEGAL
aPrice = jaguar.getPrice(); //LEGAL
aProfit = jaguar.getProfit(); //ILLEGAL. getProfit is private.
aProfit = hyundai.getProfit(); //ILLEGAL. getProfit is private.
if (hyundai == jaguar) //ILLEGAL. Cannot use == with classes.
cout << "Want to swap cars?";
hyundai = jaguar; //LEGAL
16. After the change, they would all be legal except for the following, which is still illegal:
if (hyundai == jaguar) //ILLEGAL. Cannot use == with classes.
cout << "Want to swap cars?";
17. private
restricts access to function definitions to member functions of the same class. This restricts any change of private
variables to functions provided by the class author. The class author is then in control of these changes to the private
data, preventing inadvertent corruption of the class data.
Only one. The compiler warns if you have no public:
members in a class (or struct
for that matter).
None; we normally expect to find at least one private:
section in a class.
In a class, such a section is by default a private
: section.
In a struct
, such a section is by default a public:
section.
19. A possible correct answer is as follows:
double difference(BankAccount account1, BankAccount account2)
{
return (account1.getBalance() − account2.getBalance());
}
Note that the following is not correct, because balance
is a private member.
double difference(BankAccount account1, BankAccount account2)
{
return (account1.balance − account2.balance); //ILLEGAL
}
void double update(BankAccount& theAccount)
{
theAccount.update();
theAccount.update();
}
Note that since this is not a member function, you must give the object name and dot operator when you call update
.
BankAccount newAccount(BankAccount oldAccount)
{
BankAccount temp;
temp.set(0, oldAccount.getRate( ));
return temp;
}
YourClass anObject(42, 'A'); //LEGAL
YourClass anotherObject; //LEGAL
YourClass yetAnotherObject(); //PROBLEM
anObject = YourClass(99, 'B'); //LEGAL
anObject = YourClass(); //LEGAL
anObject = YourClass; //ILLEGAL
The statement marked //PROBLEM
is not, strictly speaking, illegal, but it does not mean what you might think it means. If you mean this to be a declaration of an object called yetAnotherObject
, then it is wrong. It is a correct function declaration for a function called yetAnotherObject
that takes zero arguments and that returns a value of type YourClass
, but that is not the intended meaning. As a practical matter, you can probably consider it illegal. The correct way to declare an object called yetAnotherObject
so that it will be initialized with the default constructor is as follows:
YourClass yetAnotherObject;
23. The modified class definition is as follows:
class DayOfYear
{
public:
DayOfYear(int theMonth, int theDay);
//Precondition: theMonth and theDay form a
//possible date. Initializes the date according to
//the arguments.
DayOfYear();
//Initializes the date to January first.
void input();
void output();
int getMonth();
//Returns the month, 1 for January, 2 for February, etc.
int getDay();
//Returns the day of the month.
private:
void checkDate( );
int month;
int day;
};
Notice that we have omitted the member function set
, since the constructors make set
unnecessary. You must also add the following function definitions (and delete the function definition for DayOfYear::set
):
DayOfYear::DayOfYear(int theMonth, int theDay)
{
month = theMonth;
day = theDay;
checkDate();
}
DayOfYear::DayOfYear()
{
month = 1;
day = 1;
}
24. The class definition is the same as in the previous exercise. The constructor definitions would change to the following:
DayOfYear::DayOfYear(int theMonth, int theDay)
: month(theMonth), day(theDay)
{
checkDate();
}
DayOfYear::DayOfYear() : month(1), day(1)
{
//Body intentionally empty.
}
25. The member variables should all be private. The member functions that are part of the interface for the ADT (that is, the member functions that are operations for the ADT) should be public. You may also have auxiliary helping functions that are used only in the definitions of other member functions. These auxiliary functions should be private.
26. All the declarations of private member variables are part of the implementation. (There should be no public member variables.) All the function declarations for public member functions of the class (which are listed in the class definitions) as well as the explanatory comments for these function declarations are part of the interface. All the function declarations for private member functions are part of the implementation. All member function definitions (whether the function is public or private) are part of the implementation.
27. You need to read only the interface parts. That is, you need to read only the function declarations for public members of the class (which are listed in the class definitions) as well as the explanatory comments for these function declarations. You need not read any of the function declarations of the private member functions, the declarations of the private member variables, the definitions of the public member functions, or the definitions of the private member functions.
BankAccount::BankAccount(int dollars, int cents,
double rate) : dollarsPart(dollars),
centsPart(cents),
interestRate(fraction(rate))
{
if ((dollars < 0) || (cents < 0) || (rate < 0))
{
cout << "Illegal values for money or interest rate.\n";
exit(1);
}
}
BankAccount::BankAccount(int dollars, double rate)
: dollarsPart(dollars), centsPart(0),
interestRate(fraction(rate))
{
if ((dollars < 0) || (rate < 0))
{
cout << "Illegal values for money or interest rate.\n";
exit(1);
}
29. Functions and data defined for the parent class can be made available in the derived class, eliminating the need to redefine the functions and data again in the derived class. This enhances maintainability because there is now no duplication of code among multiple classes and hence only a single location in the code that may be subject to change. Additionally, inheritance provides a clean way to isolate code that is only applicable to a derived class. Since such code only appears in the definition of the derived class, it is usually easier to read.
30. No, but a derived class can indirectly access a private member variable of the parent class through a public function.
31. Yes, the derived class will have access to the same functions. In Chapter 15 we will discuss how we can make the functions do different things for an object of class SportsCar
versus an object of class Automobile
.