目录
- 练习1.1
- 题目
- 答案
- 练习1.2
- 题目
- 答案
- 练习1.3
- 题目
- 答案
- 练习1.4
- 题目
- 答案
- 练习1.5
- 题目
- 答案
- 练习1.6
- 题目
- 答案
- 参考
练习1.1
题目
修改下面的Employee结构体,将其放在一个名为HR的名称空间中。你必须对main()中的代码进行那些修改才能使用此新实现?此外,修改代码使用C++20的指派初始化器。
// employee模块接口文件
export module employee;
export struct Employee {
char firstInitial;
char lastInitial;
int employeeNumber;
int salary;
};
// main
// import <iostream>;
// import <format>;
import std.core;
import employee;
int main() {
Employee anEmployee;
anEmployee.firstInitial = 'J';
anEmployee.lastInitial = 'D';
anEmployee.employeeNumber = 42;
anEmployee.salary = 80'000;
std::cout << std::format("Employee: {}{}\n", anEmployee.firstInitial, anEmployee.lastinitial);
std::cout << std::format("Number: {}\n", anEmployee.employeeNumber);
std::cout << std::format("Salary: ${}\n", anEmployee.salary);
}
答案
// employee模块接口文件
export module employee;
namespace HR {
export struct Employee {
char firstInitial;
char lastInitial;
int employeeNumber;
int salary;
};
}
// main()
import std.core;
import employee;
int main() {
HR::Employee anEmployee{
.firstInitial = 'J',
.lastInitial = 'D',
.employeeNumber = 42,
.salary = 80'000
};
std::cout << std::format("Employee: {}{}\n", anEmployee.firstInitial, anEmployee.lastInitial);
std::cout << std::format("Number: {}\n", anEmployee.employeeNumber);
std::cout << std::format("Salary: {}\n", anEmployee.salary);
}
练习1.2
题目
以练习1.1的结果为基础,并向Employee添加一个枚举数据成员title,以指定某个雇员是经理,高级工程师还是工程师。你将选用哪种枚举类型?无论需要添加什么,都将其添加到HR名称空间中。在main()函数中测试新的Employee数据成员。使用switch语句为title打印出易于理解的字符串。
答案
// employee模块接口文件
export module employee;
namespace HR {
export enum class position {
MANAGER,
ENGINEER,
SENIOR_ENGINEER
};
export struct Employee {
char firstInitial;
char lastInitial;
int employeeNumber;
int salary;
position title;
};
}
// main()
import std.core;
import employee;
int main() {
std::string title;
HR::Employee anEmployee{
.firstInitial = 'J',
.lastInitial = 'D',
.employeeNumber = 42,
.salary = 80'000,
.title = HR::position::ENGINEER
};
std::cout << std::format("Employee: {}{}\n", anEmployee.firstInitial, anEmployee.lastInitial);
std::cout << std::format("Number: {}\n", anEmployee.employeeNumber);
std::cout << std::format("Salary: {}\n", anEmployee.salary);
switch (anEmployee.title) {
case HR::position::ENGINEER:
title = "Engineer";
break;
case HR::position::MANAGER:
title = "Manager";
break;
case HR::position::SENIOR_ENGINEER:
title = "Senior Engineer";
break;
}
if (!title.empty()) {
std::cout << std::format("Title: {}\n", title);
}
}
练习1.3
题目
使用std::array存储练习1.2中具有不同数据的3个Employee实例,然后使用基于范围的for循环打印出array中的雇员。
答案
// main()
import std.core;
import employee;
static const std::string title(HR::position pos) {
std::string title;
switch (pos) {
case HR::position::ENGINEER:
title = "Engineer";
break;
case HR::position::MANAGER:
title = "Manager";
break;
case HR::position::SENIOR_ENGINEER:
title = "Senior Engineer";
break;
}
return title;
}
static void display(HR::Employee employee) {
std::cout << std::format("Employee: {} {}\n", employee.firstInitial, employee.lastInitial);
std::cout << std::format("Number: {}\n", employee.employeeNumber);
std::cout << std::format("Salary: {}\n", employee.salary);
std::cout << std::format("Title: {}\n\n", title(employee.title));
}
int main() {
std::array<HR::Employee, 3> employees{ {
{'J', 'D', 42, 80'000, HR::position::MANAGER },
{'A', 'H', 43, 60'000, HR::position::SENIOR_ENGINEER },
{'C', 'B', 44, 40'000, HR::position::ENGINEER }
}};
for (auto& employee : employees) {
display(employee);
}
}
练习1.4
题目
进行与练习1.3相同的操作,但使用std::vector而不是array,并使用push_back()将元素插入vector中。
答案
// main()
import std.core;
import employee;
static const std::string title(HR::position pos) {
std::string title;
switch (pos) {
case HR::position::ENGINEER:
title = "Engineer";
break;
case HR::position::MANAGER:
title = "Manager";
break;
case HR::position::SENIOR_ENGINEER:
title = "Senior Engineer";
break;
}
return title;
}
static void display(HR::Employee employee) {
std::cout << std::format("Employee: {} {}\n", employee.firstInitial, employee.lastInitial);
std::cout << std::format("Number: {}\n", employee.employeeNumber);
std::cout << std::format("Salary: {}\n", employee.salary);
std::cout << std::format("Title: {}\n\n", title(employee.title));
}
int main() {
HR::Employee employee1 { 'J', 'D', 42, 80'000, HR::position::MANAGER };
HR::Employee employee2 { 'A', 'H', 43, 60'000, HR::position::SENIOR_ENGINEER };
HR::Employee employee3 { 'C', 'B', 44, 40'000, HR::position::ENGINEER };
std::vector<HR::Employee> employees;
employees.push_back(employee1);
employees.push_back(employee2);
employees.push_back(employee3);
for ( auto& employee : employees ) {
display(employee);
}
}
练习1.5
题目
修改下面的AirlineTicket类,以尽可能地使用引用,并正确使用const。
// airline_ticket模块接口文件
export module airline_ticket;
// import <string>;
import std.core; // MSVC
export class AirlineTicket {
public:
AirlineTicket(); // constructor
~AirlineTicket(); // destructor
double calculatePriceInDollars();
std::string getPassengerName();
void setPassengerName(std::string name);
int getNumberOfMiles();
void setNumberOfMiles(int miles);
bool hasEliteSuperRewardsStatus();
void setHasEliteSuperRewardsStatus(bool status);
private:
std::string m_passengerName;
int m_numberOfMiles;
bool m_hasEliteSuperRewardsStatus;
};
// airline_ticket模块实现文件
module airline_ticket;
AirlineTicket::AirlineTicket() :
m_passengerName{ "Unknown Passenger" },
m_numberOfMiles{ 0 },
m_hasEliteSuperRewardsStatus{ false } {
}
AirlineTicket::~AirlineTicket() {
// nothong to do in terms of cleanup.
}
double AirlineTicket::calculatePriceInDollars() {
if (hasEliteSuperRewardsStatus()) {
// elite super rewards customers fly for free!
return 0;
}
// the cost of the ticket is the number of milies times 0.1.
// real airlines probably have a more complicated formula!
return getNumberOfMiles() * 0.1;
}
std::string AirlineTicket::getPassengerName() {
return m_passengerName;
}
void AirlineTicket::setPassengerName(std::string name) {
m_passengerName = name;
}
int AirlineTicket::getNumberOfMiles() {
return m_numberOfMiles;
}
void AirlineTicket::setNumberOfMiles(int miles) {
m_numberOfMiles = miles;
}
bool AirlineTicket::hasEliteSuperRewardsStatus() {
return m_hasEliteSuperRewardsStatus;
}
void AirlineTicket::setHasEliteSuperRewardsStatus(bool status) {
m_hasEliteSuperRewardsStatus = status;
}
答案
// airline_ticket模块接口文件
export module airline_ticket;
// import <string>;
import std.core; // MSVC
export class AirlineTicket {
public:
AirlineTicket(); // constructor
~AirlineTicket(); // destructor
double calculatePriceInDollars() const;
const std::string& getPassengerName() const;
void setPassengerName(const std::string& name);
int getNumberOfMiles() const;
void setNumberOfMiles(int miles);
bool hasEliteSuperRewardsStatus() const;
void setHasEliteSuperRewardsStatus(bool status);
private:
std::string m_passengerName;
int m_numberOfMiles;
bool m_hasEliteSuperRewardsStatus;
};
// airline_ticket模块实现文件
module airline_ticket;
AirlineTicket::AirlineTicket() :
m_passengerName{ "Unknown Passenger" },
m_numberOfMiles{ 0 },
m_hasEliteSuperRewardsStatus{ false } {
}
AirlineTicket::~AirlineTicket() {
// nothong to do in terms of cleanup.
}
double AirlineTicket::calculatePriceInDollars() const {
if (hasEliteSuperRewardsStatus()) {
// elite super rewards customers fly for free!
return 0;
}
// the cost of the ticket is the number of milies times 0.1.
// real airlines probably have a more complicated formula!
return getNumberOfMiles() * 0.1;
}
const std::string& AirlineTicket::getPassengerName() const {
return m_passengerName;
}
void AirlineTicket::setPassengerName(const std::string& name) {
m_passengerName = name;
}
int AirlineTicket::getNumberOfMiles() const {
return m_numberOfMiles;
}
void AirlineTicket::setNumberOfMiles(int miles) {
m_numberOfMiles = miles;
}
bool AirlineTicket::hasEliteSuperRewardsStatus() const {
return m_hasEliteSuperRewardsStatus;
}
void AirlineTicket::setHasEliteSuperRewardsStatus(bool status) {
m_hasEliteSuperRewardsStatus = status;
}
练习1.6
题目
修改练习1.5中的AirlineTicket类,使其包含一个可选的常旅客号码。表示此可选数据成员的最佳方法是什么?添加一个设置器和获取器来设置和获取常旅客号码。修改main()函数以测试你的实现。
答案
// airline_ticket模块接口文件
export module airline_ticket;
// import <string>;
import std.core; // MSVC
export class AirlineTicket {
public:
AirlineTicket(); // constructor
~AirlineTicket(); // destructor
double calculatePriceInDollars();
std::string getPassengerName();
void setPassengerName(std::string name);
int getNumberOfMiles();
void setNumberOfMiles(int miles);
void setFrequentFlyerNumber(int frequentFlyerNumber);
std::optional<int> getFrequentFlyerNumber() const;
bool hasEliteSuperRewardsStatus();
void setHasEliteSuperRewardsStatus(bool status);
private:
std::string m_passengerName;
int m_numberOfMiles;
std::optional<int> m_frequentFlyerNumber;
bool m_hasEliteSuperRewardsStatus;
};
// airline_ticket模块实现文件
module airline_ticket;
AirlineTicket::AirlineTicket() :
m_passengerName{ "Unknown Passenger" },
m_numberOfMiles{ 0 },
m_hasEliteSuperRewardsStatus{ false } {
}
AirlineTicket::~AirlineTicket() {
// nothong to do in terms of cleanup.
}
double AirlineTicket::calculatePriceInDollars() {
if (hasEliteSuperRewardsStatus()) {
// elite super rewards customers fly for free!
return 0;
}
// the cost of the ticket is the number of milies times 0.1.
// real airlines probably have a more complicated formula!
return getNumberOfMiles() * 0.1;
}
std::string AirlineTicket::getPassengerName() {
return m_passengerName;
}
void AirlineTicket::setPassengerName(std::string name) {
m_passengerName = name;
}
int AirlineTicket::getNumberOfMiles() {
return m_numberOfMiles;
}
void AirlineTicket::setNumberOfMiles(int miles) {
m_numberOfMiles = miles;
}
void AirlineTicket::setFrequentFlyerNumber(int frequentFlyerNumber) {
m_frequentFlyerNumber = frequentFlyerNumber;
}
std::optional<int> AirlineTicket::getFrequentFlyerNumber() const {
return m_frequentFlyerNumber;
}
bool AirlineTicket::hasEliteSuperRewardsStatus() {
return m_hasEliteSuperRewardsStatus;
}
void AirlineTicket::setHasEliteSuperRewardsStatus(bool status) {
m_hasEliteSuperRewardsStatus = status;
}
// main()
import std.core;
import airline_ticket;
int main() {
AirlineTicket myTicket;
myTicket.setPassengerName("Sherman T. Socketwrench");
myTicket.setNumberOfMiles(700);
myTicket.setFrequentFlyerNumber(123'456);
const double cost{ myTicket.calculatePriceInDollars() };
std::cout << std::format("This ticket will cost ${}\n", cost);
const auto frequentFlyerNumber{ myTicket.getFrequentFlyerNumber() };
if (frequentFlyerNumber) {
std::cout << std::format("Frequent flyer number: {}\n", frequentFlyerNumber.value());
}
else {
std::cout << "No frequent flyer number.\n";
}
}
参考
[比] 马克·格雷戈勒著 程序喵大人 惠惠 墨梵 译 C++20高级编程(第五版)