C++ primer5 7.21/7.22/7.23-24/7.26/7.27/7.41/7.57

7.21 修改Sales_data类使其隐藏实现的细节strcut-class

#ifndef ex7_21_h
#define ex7_21_h

#include <string>
#include <iostream>
using namespace std;

class Sales_data 
{   //友元函数,可以访问类的私有成员
    friend istream &read(istream &is, Sales_data &item);
    friend ostream &print(ostream &os, const Sales_data &item);
    friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs);

public:
    Sales_data() = default;//添加类的构造器-默认
    Sales_data(const string &s):bookNo(s) {}
    Sales_data(const string &s, unsigned &n, double &p) : bookNo(s), units_sold(n), revenue(n*p) {}
    Sales_data(istream &is) {read(is, *this);}//从键盘输入的参数执行初始化-成员函数

    string isbn() const {return bookNo;}; //成员函数的类内定义
    Sales_data& combine(const Sales_data&);

private: //私有成员,封装隐藏实现细节
    string bookNo;          //书号
    unsigned units_sold = 0; //销量
    double revenue = 0.0; //销售额
};

//成员函数的类外定义
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    units_sold += rhs.units_sold;//销量相加
    revenue += rhs.revenue;    //总销售额相加
}
//友元函数类外定义,可以访问类的私有成员
istream &read(istream &is, Sales_data &item)         //读取对象
{
    double price = 0; //单价
    is >> item.bookNo >> item.units_sold >> price;  //读入书名、销量、单价
    item.revenue = price * item.units_sold;        //计算销售额=销量*单价
}

ostream &print(ostream &os, const Sales_data &item) //打印对象
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue;
    return os; //打印:书名、销量、销售额
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)//对象相加
{
    Sales_data sum = lhs;
    sum.combine(rhs);
    return sum;
}
#endif

7.22 修改Person类使其隐藏实现的细节strcut-class

#ifndef ex7_22_h
#define ex7_22_h

#include <string>
#include <iostream>
using namespace std;

class Person
{   //友元函数声明,可以访问类的私有成员
    friend std::istream &read(std::istream &is, Person &person);       //读对象
    friend std::ostream &print(std::ostream &os, const Person &person);//打印对象

public:
    Person() = default; //默认构造函数
    Person(const std::string sname, const std::string saddr):name(sname), address(saddr){ }
    Person(std::istream &is){ read(is, *this); }

    std::string getName() const { return name; }
    std::string getAddress() const { return address; }

private://私有成员,封装实现细节
    std::string name;    //名字
    std::string address; //住址
};
//友元函数的类外定义
std::istream &read(std::istream &is, Person &person)
{
    is >> person.name >> person.address;
    return is;
}

std::ostream &print(std::ostream &os, const Person &person)
{
    os << person.name << " " << person.address;
    return os;
}
#endif

7.23-24 编写自己的Screen类

#ifndef ex7_24_h
#define ex7_24_h

#include <string>
using namespace std;

class Screen //窗口类
{
public:
    using pos = string::size_type;

    Screen() = default; //构造函数定义屏幕的尺寸和内容 //1默认构造函数
    Screen(pos ht, pos wd):height(ht), width(wd), contents(ht*wd, ' '){ } //2接受高和宽
    Screen(pos ht, pos wd, char c):height(ht), width(wd), contents(ht*wd, c){} 
    //3接受一个字符作为屏幕初始内容
    //定义在类内部的函数自动内联
    char get() const { return contents[cursor]; } //读取光标处的字符内容
    char get(pos r, pos c) const { return contents[r*width+c]; } //移动光标

private:
    pos cursor = 0; //光标位置
    pos height = 0, width = 0; //屏幕的高和宽
    string contents; //屏幕内容
};
#endif

7.26 将Sales_data::avg_price定义成内联函数

#ifndef ex7_26_h
#define ex7_26_h

#include <string>
#include <iostream>
using namespace std;
class Sales_data 
{   //友元函数,可以访问类的私有成员
    friend istream &read(istream &is, Sales_data &item);
    friend ostream &print(ostream &os, const Sales_data &item);
    friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs);

public:
    Sales_data() = default;//添加类的构造器-默认
    Sales_data(const string &s):bookNo(s) {}
    Sales_data(const string &s, unsigned &n, double &p) : bookNo(s), units_sold(n), revenue(n*p) {}
    Sales_data(istream &is) {read(is, *this);}//从键盘输入的参数执行初始化-成员函数

    string isbn() const {return bookNo;}; //成员函数的类内定义
    Sales_data& combine(const Sales_data&);

private:
    inline double avg_price() const; //内联函数,均价

private:
    string bookNo;          //书号
    unsigned units_sold = 0; //销量
    double revenue = 0.0; //销售额
};

inline
double Sales_data::avg_price() const
{
    return units_sold ? revenue/units_sold : 0;
}

//成员函数的类外定义
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    units_sold += rhs.units_sold;//销量相加
    revenue += rhs.revenue;    //总销售额相加
}
//友元函数类外定义,可以访问类的私有成员
istream &read(istream &is, Sales_data &item)         //读取对象
{
    double price = 0; //单价
    is >> item.bookNo >> item.units_sold >> price;  //读入书名、销量、单价
    item.revenue = price * item.units_sold;        //计算销售额=销量*单价
}

ostream &print(ostream &os, const Sales_data &item) //打印对象
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue;
    return os; //打印:书名、销量、销售额
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)//对象相加
{
    Sales_data sum = lhs;
    sum.combine(rhs);
    return sum;
}
#endif

7.27 给Screen类添加move、set、display函数,执行代码检验是否正确

#ifndef ex7_27_h
#define ex7_27_h

#include <string>
#include <iostream>
using namespace std;

class Screen //窗口类
{
public:
    using pos = string::size_type;

    Screen() = default; //构造函数定义屏幕的尺寸和内容 //1默认构造函数
    Screen(pos ht, pos wd):height(ht), width(wd), contents(ht*wd, ' '){ } //2接受高和宽
    Screen(pos ht, pos wd, char c):height(ht), width(wd), contents(ht*wd, c){} 
    //3接受一个字符作为整个屏幕的初始内容
    //定义在类内部的函数自动内联
    char get() const { return contents[cursor]; } //读取光标处的字符内容
    char get(pos r, pos c) const { return contents[r*width+c]; } //移动光标

    inline Screen& move(pos r, pos c); 
    inline Screen& set(char c); //三个内联函数都必须是返回引用
    inline Screen& set(pos r, pos c, char ch);
    
    const Screen& display(std::ostream& os) const
    {
        do_display(os);
        return *this;
    }
    Screen& display(std::ostream& os)
    {
        do_display(os);
        return *this;
    }

private: //显示屏幕内容
    void do_display(std::ostream& os) const { os << contents; }

private:
    pos cursor = 0; //光标位置
    pos height = 0, width = 0; //屏幕的高和宽
    string contents; //屏幕内容
};

inline Screen& Screen::move(pos r, pos c)
{
    cursor = r * width + c; //移动光标到指定行、列位置
    return *this;
}

inline Screen& Screen::set(char c)
{
    contents[cursor] = c;         //设置当前位置光标所在新值
    return *this;
}

inline Screen& Screen::set(pos r, pos c, char ch)
{
    contents[r * width + c] = ch; //设置给定位置的新值
    return *this;
}
#endif
//ex7_27.cpp
#include "ex7_27.h"
using namespace std;
int main()
{
   Screen myScreen(5, 5, 'X');//屏幕高宽都是5,在5*4+0即第21列位置将X置为#
   myScreen.move(4, 0).set('#').display(cout);
   cout << "\n";
   myScreen.display(cout);
   cout << "\n";

   system("pause");
   return 0;
}

在这里插入图片描述

7.32 定义Screen和Window_mgr,其中clear是Window_mgr的成员,是Screen的友元

#ifndef ex7_32_h
#define ex7_32_h

#include <string>
#include <iostream>
#include <vector>
using namespace std;
class Window_mgr //窗口管理类
{
public:
    using ScreenIndex = vector<Screen>::size_type; //窗口中每个屏幕的编号
    inline void clear(ScreenIndex);//按照编号将指定Screen的内容设置为空白
    
private:
    vector<Screen> screens;
};

class Screen //屏幕类
{   //友元函数可以访问Screen类的私有成员
    friend void Window_mgr::clear(ScreenIndex);//指定Screen的内容设置为空白
public:
    using pos = string::size_type;

    Screen() = default; //构造函数定义屏幕的尺寸和内容 //1默认构造函数
    Screen(pos ht, pos wd):height(ht), width(wd), contents(ht*wd, ' '){ } //2接受高和宽
    Screen(pos ht, pos wd, char c):height(ht), width(wd), contents(ht*wd, c){} 
    //3接受一个字符作为屏幕初始内容
    //定义在类内部的函数自动内联
    char get() const { return contents[cursor]; } //读取光标处的字符内容
    char get(pos r, pos c) const { return contents[r*width+c]; } //移动光标

    inline Screen& move(pos r, pos c); 
    inline Screen& set(char c);
    inline Screen& set(pos r, pos c, char ch);
    
    const Screen& display(std::ostream& os) const
    {
        do_display(os);
        return *this;
    }
    Screen& display(std::ostream& os)
    {
        do_display(os);
        return *this;
    }

private: //显示屏幕内容
    void do_display(std::ostream& os) const { os << contents; }

private:
    pos cursor = 0; //光标位置
    pos height = 0, width = 0; //屏幕的高和宽
    string contents; //屏幕内容
};

inline void Window_mgr::clear(ScreenIndex i)
{
    if (i >= screens.size()) 
        return; // judge for out_of_range.
    Screen& s = screens[i];
    s.contents = std::string(s.height * s.width, ' ');
}


inline Screen& Screen::move(pos r, pos c)
{
    cursor = r * width + c; //移动光标到指定行、列位置
    return *this;
}

inline Screen& Screen::set(char c)
{
    contents[cursor] = c;         //设置当前位置光标所在新值
    return *this;
}

inline Screen& Screen::set(pos r, pos c, char ch)
{
    contents[r * width + c] = ch; //设置给定位置的新值
    return *this;
}
#endif

7.41 委托构造函数,给每个构造函数体添加一条语句,令其一旦执行就打印一条信息,理解委托构造函数的执行顺序

#ifndef ex7_41_h
#define ex7_41_h

#include <string>
#include <iostream>
#include <vector>
using namespace std;
class Sales_data 
{   //友元函数,可以访问类的私有成员
    friend istream &read(istream &is, Sales_data &item);
    friend ostream &print(ostream &os, const Sales_data &item);
    friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs);

public:
    Sales_data(const string &s, unsigned &n, double &p) : bookNo(s), units_sold(n), revenue(n*p) 
    { std::cout << "Sales_data(const std::string&, unsigned, double)" << std::endl; }

    Sales_data() : Sales_data("", 0, 0.0f)
    { std::cout << "Sales_data()" << std::endl; }
    
    Sales_data(const std::string &s) : Sales_data(s, 0, 0.0f)
    { std::cout << "Sales_data(const std::string&)" << std::endl; }
    
    Sales_data(std::istream &is);

    string isbn() const {return bookNo;}; //成员函数的类内定义
    Sales_data& combine(const Sales_data&);

private:
    inline double avg_price() const;

private:
    string bookNo;          //书号
    unsigned units_sold = 0; //销量
    double revenue = 0.0; //销售额
};

inline
double Sales_data::avg_price() const
{
    return units_sold ? revenue/units_sold : 0;
}

//成员函数的类外定义
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    units_sold += rhs.units_sold;//销量相加
    revenue += rhs.revenue;    //总销售额相加
}
//友元函数类外定义,可以访问类的私有成员
istream &read(istream &is, Sales_data &item)         //读取对象
{
    double price = 0; //单价
    is >> item.bookNo >> item.units_sold >> price;  //读入书名、销量、单价
    item.revenue = price * item.units_sold;        //计算销售额=销量*单价
}

ostream &print(ostream &os, const Sales_data &item) //打印对象
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue;
    return os; //打印:书名、销量、销售额
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)//对象相加
{
    Sales_data sum = lhs;
    sum.combine(rhs);
    return sum;
}
#endif
//ex7_41.cpp
#include "ex7_41.h"
using namespace std;
int main()
{
   cout << "1. default way: " << endl;
    cout << "----------------" << endl;
    Sales_data s1;

    cout << "\n2. use std::string as parameter: " << endl;
    cout << "----------------" << endl;
    Sales_data s2("CPP-Primer-5th");

    cout << "\n3. complete parameters: " << endl;
    cout << "----------------" << endl;
    Sales_data s3("CPP-Primer-5th", 3, 25.8);

    cout << "\n4. use istream as parameter: " << endl;
    cout << "----------------" << endl;
    Sales_data s4(std::cin);


   system("pause");
   return 0;
}

7.57 定义账户类-含有static成员

#ifndef ex7_57_h
#define ex7_57_h

#include <string>
#include <iostream>
#include <vector>
using namespace std;
class Account //账户类
{
public:
    void caculate() { amount += amount * interestRate; }
    static double rate() { return interestRate; }
    static void rate(double newRate) { interestRate = newRate} //静态数据成员可以作默认实参

private:
    string owner;
    double amount;
    static double interestRate;
    static constexpr double todayRate = 42.42; //内部初始化需要constexpr
    static double initRate() { return todayRate; } //今天的基准利率
};
double Account::interestRate = initRate(); //外部初始化不加static关键字,关键字出现在类内部声明
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值