# C++Primer学习笔记之第七章

第七章 类 __C++Primer第五版

# C++Primer学习笔记之第七章_第1张图片
类.png

定义抽象数据类型

7.1 练习

#include 
#include 
using namespace std;

//struct 和 class 的唯一区别是默认的访问权限。
//struct默认是public
//class默认是private

struct Sales_data
{
    string bookNo; //编号
    unsigned units_sold = 0; //卖出的数量, 类初始化,C++新标准,vs2010不支持
    double revenue = 0; //总金额
};

int main()
{
    Sales_data total;
    if (cin >> total.bookNo >> total.units_sold >> total.revenue)
    {
        Sales_data trans;
        while(cin >> trans.bookNo >> trans.units_sold >> trans.revenue)
        {
            if (trans.bookNo == total.bookNo)
            {
                total.units_sold += trans.units_sold;
                total.revenue += trans.revenue;
            }
            else
            {
                cout << total.bookNo << "\t" << total.units_sold << "\t" << total.revenue << endl;
                total = trans;
            }
        }
        cout << total.bookNo << "\t" << total.units_sold << "\t" << total.revenue << endl;
    }
    else
    {
        cerr << "No data?" << endl;
        return -1; //表示失败

    }

    return 0;
}

定义改进的Sales_data类

#ifndef SALES_DATA_H
#define SALES_DATA_H

#include 
#include 

struct Sales_data 
{
    //成员函数
    //获得isbn编号
    std::string isbn() const //const成员函数
    {
        return this->bookNo;
    }

    Sales_data& combine(const Sales_data&);

    double avg_price() const; //const成员函数


    //数据成员
    std::string bookNo;
    unsigned units_sole;
    double revenue;
};

//非成员函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);
std::istream& read(std::istream&, Sales_data&);

//对未定义的成员函数在类外进行定义
double Sales_data::avg_price() const
{
    if (units_sold)
    {
        return revenue/units_sold;
    }
    else
    {
        return 0;
    }
}

//定义一个返回this对象的函数
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    this->units_sold += rhs.units_sold;
    this->revenue += rhs.revenue;
    return *this; //返回调用该函数的对象
}

//对非成员函数定义
std::istream& read(std::istream &is, Sales_data &item)
{
    double price = 0;
    //输入isbn编号, 卖出数量, 单价
    is >> item.bookNo >> item.units_sold >> price; 
    item.revenue = item.units_sold * price;
    return is;
}
std::ostream& print(std::ostream &os, const Sales_data &item)
{
    os << item.isbn() << "  " << item.units_sold << "  " 
        << item.revenue << "  " << item.avg_price();
    return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
    //把lhs的数据成员拷贝给sum
    //默认情况下,拷贝类的对象其实拷贝的是对象的数据成员
    Sales_data sum = lhs; 
    sum.combine(rhs);
    return sum;
}
#endif

引入const成员函数

上面Sales_data类中的isbn()avg_price()函数都是常量成员函数。紧跟在参数列表后面的const表示this是一个指向常量的常量指针也就是const Sales_data const *类型,如果没有列表后面的const,this的类型是Sales_data const *类型。

常量对象以及常量对象的引用或指针都只能调用常量成员函数。

7.3 7.7练习题

#include 
#include 
#include "Sales_data.h"
using namespace std;

int main()
{
    Sales_data total;
    if (read(cin, total))
    {
        Sales_data trans;
        while(read(cin, trans))
        {
            if (trans.isbn() == total.isbn())
            {
                total.combine(trans);
            }
            else
            {
                print(cout, total);
                total = trans;
            }
        }
        print(cout, total);
    }
    else 
    {
        cout << "No Data?" << endl;
        return -1;
    }
    return 0;
}

7.4 7.5 7.9练习

编写一个名为Person的类,使其表示人员的姓名和住址。使用string对象存放这些元素,接下来的练习将不断充实这个类的其他特征。

#ifndef PERSON_H
#define PERSON_H

#include 
#include 

struct Person
{
    //数据成员
    std::string name;
    std::string address;

    //成员函数
    //返回name
    std::string getName() const
    {
        return this->name;
    }
    //返回address
    std::string getAddress() const{
        return this->address;
    }
};

std::ostream& print(std::ostream &os, const Person &p)
{
    os << p.getName() << "的地址是" << person.getAddress() << endl;
    return os;
}

std::istream& read(std::istream &is, Person &p)
{
    is >> p.name >> p.address;
    return is;
}

#endif
//练习7.5的 main.cpp
#include 
#include 
#include "Person.h"
using namespace std;

int main()
{
    Person person;
    //person.name = "MangoLee";
    //person.address = "Beijing";

    cin >> person.name >> person.address;

    cout << person.getName() << "的地址是" << person.getAddress() << endl;

    system("pause");
    return 0;
}

//练习7.9的main.cpp
int main()
{
    Person person;

    read(cin, person);
    print(cout, person);

    system("pause");
    return 0;
}

构造函数

默认构造函数

默认构造函数按照如下规则初始化类的数据成员:

  • 如果存在类内的初始值,用它来初始化成员(C++11)

  • struct Person
    {
      string name = 'mango';  //类内初始化,vs2010不支持此C++11新特性
          int age = 26; //类内初始化,vs2010不支持此C++11新特性
    }
    
  • 否则,默认初始化该成员

    • 如果是内置类型,定义于任何函数体之外的变量被初始化为0;定义在函数体内部的不被初始化
    • 每个类调用默认初始化

7.11-1.13 练习

为Sales_data添加构造函数,并用istream构造函数重写229页程序。

#ifndef SALES_DATA_H
#define SALES_DATA_H

#include 
#include 

struct Sales_data 
{
    //构造函数
    Sales_data();
    Sales_data(const std::string &str):
        bookNo(str),units_sold(0),revenue(0){}
    //初始化列表
    Sales_data(const std::string &str, unsigned n, double p):
        bookNo(str),units_sold(n),revenue(p){}
    Sales_data(std::istream &is);
  
    //成员函数
    //获得isbn编号
    std::string isbn() const
    {
        return this->bookNo;
    }
    Sales_data& combine(const Sales_data&);
    double avg_price() const;

    //数据成员
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};

//非成员函数声明
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);
std::istream& read(std::istream&, Sales_data&);

Sales_data::Sales_data(std::istream &is)
{
    read(is, *this); //*this 代表本身
}

//对未定义的成员函数在类外进行定义
double Sales_data::avg_price() const
{
    if (units_sold)
    {
        return revenue/units_sold;
    }
    else
    {
        return 0;
    }
}

//定义一个返回this对象的函数
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    this->units_sold += rhs.units_sold;
    this->revenue += rhs.revenue;
    return *this; //返回调用该函数的对象
}

//对非成员函数定义
std::istream& read(std::istream &is, Sales_data &item)
{
    double price = 0;
    //输入isbn编号, 卖出数量, 单价
    is >> item.bookNo >> item.units_sold >> price; 
    item.revenue = item.units_sold * price;
    return is;
}
std::ostream& print(std::ostream &os, const Sales_data &item)
{
    os << item.isbn() << "  " << item.units_sold << "  " 
        << item.revenue << "  " << item.avg_price();
    return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
    //把lhs的数据成员拷贝给sum
    //默认情况下,拷贝类的对象其实拷贝的是对象的数据成员
    Sales_data sum = lhs; 
    sum.combine(rhs);
    return sum;
}
#endif

访问控制和封装

引入public 和private的关键词。

//Sales.data.h添加访问控制,函数实现不变。
class Sales_data 
{
public:
    Sales_data();
    Sales_data(const std::string &str):
        bookNo(str),units_sold(0),revenue(0){}
    Sales_data(const std::string &str, unsigned n, double p):
        bookNo(str),units_sold(n),revenue(p){}
    Sales_data(std::istream &is);
    std::string isbn() const{return this->bookNo;}
    Sales_data& combine(const Sales_data&);
private:
    double avg_price() const;
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};

友元

类可以允许友元类和友元函数访问它的私有成员。

//Sales.data.h添加友元函数
class Sales_data 
{
  //友元声明,不代表普通声明,函数需要声明仍需要在类外进行声明
    friend Sales_data add(const Sales_data&, const Sales_data&);
    friend std::ostream& print(std::ostream&, const Sales_data&);
    friend std::istream& read(std::istream&, Sales_data&);
  
public:
    Sales_data();
    Sales_data(const std::string &str):
        bookNo(str),units_sold(0),revenue(0){}
    Sales_data(const std::string &str, unsigned n, double p):
        bookNo(str),units_sold(n),revenue(p){}
    Sales_data(std::istream &is);
    std::string isbn() const{return this->bookNo;}
    Sales_data& combine(const Sales_data&);
private:
    double avg_price() const;
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};
//非成员函数声明
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);
std::istream& read(std::istream&, Sales_data&);

7.22 练习

class Person
{
private:
    std::string name;
    std::string address;
public:
    std::string getName() const
    {
        return this->name;
    }
    std::string getAddress() const{
        return this->address;
    }
};

你可能感兴趣的:(# C++Primer学习笔记之第七章)