# C++Primer學(xué)習(xí)筆記之第七章

第七章 類 __C++Primer第五版

類.png

定義抽象數(shù)據(jù)類型

7.1 練習(xí)

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

//struct 和 class 的唯一區(qū)別是默認(rèn)的訪問權(quán)限。
//struct默認(rèn)是public
//class默認(rèn)是private

struct Sales_data
{
    string bookNo; //編號(hào)
    unsigned units_sold = 0; //賣出的數(shù)量, 類初始化,C++新標(biāo)準(zhǔn),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;
}

定義改進(jìn)的Sales_data類

#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <iostream>
#include <string>

struct Sales_data 
{
    //成員函數(shù)
    //獲得isbn編號(hào)
    std::string isbn() const //const成員函數(shù)
    {
        return this->bookNo;
    }

    Sales_data& combine(const Sales_data&);

    double avg_price() const; //const成員函數(shù)


    //數(shù)據(jù)成員
    std::string bookNo;
    unsigned units_sole;
    double revenue;
};

//非成員函數(shù)
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);
std::istream& read(std::istream&, Sales_data&);

//對(duì)未定義的成員函數(shù)在類外進(jìn)行定義
double Sales_data::avg_price() const
{
    if (units_sold)
    {
        return revenue/units_sold;
    }
    else
    {
        return 0;
    }
}

//定義一個(gè)返回this對(duì)象的函數(shù)
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    this->units_sold += rhs.units_sold;
    this->revenue += rhs.revenue;
    return *this; //返回調(diào)用該函數(shù)的對(duì)象
}

//對(duì)非成員函數(shù)定義
std::istream& read(std::istream &is, Sales_data &item)
{
    double price = 0;
    //輸入isbn編號(hào), 賣出數(shù)量, 單價(jià)
    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的數(shù)據(jù)成員拷貝給sum
    //默認(rèn)情況下,拷貝類的對(duì)象其實(shí)拷貝的是對(duì)象的數(shù)據(jù)成員
    Sales_data sum = lhs; 
    sum.combine(rhs);
    return sum;
}
#endif

引入const成員函數(shù)

上面Sales_data類中的isbn()avg_price()函數(shù)都是常量成員函數(shù)。緊跟在參數(shù)列表后面的const表示this是一個(gè)指向常量的常量指針也就是const Sales_data const *類型,如果沒有列表后面的const,this的類型是Sales_data const *類型。

常量對(duì)象以及常量對(duì)象的引用或指針都只能調(diào)用常量成員函數(shù)。

7.3 7.7練習(xí)題

#include <iostream>
#include <string>
#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練習(xí)

編寫一個(gè)名為Person的類,使其表示人員的姓名和住址。使用string對(duì)象存放這些元素,接下來的練習(xí)將不斷充實(shí)這個(gè)類的其他特征。

#ifndef PERSON_H
#define PERSON_H

#include <iostream>
#include <string>

struct Person
{
    //數(shù)據(jù)成員
    std::string name;
    std::string address;

    //成員函數(shù)
    //返回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
//練習(xí)7.5的 main.cpp
#include <iostream>
#include <string>
#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;
}

//練習(xí)7.9的main.cpp
int main()
{
    Person person;

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

    system("pause");
    return 0;
}

構(gòu)造函數(shù)

默認(rèn)構(gòu)造函數(shù)

默認(rèn)構(gòu)造函數(shù)按照如下規(guī)則初始化類的數(shù)據(jù)成員:

  • 如果存在類內(nèi)的初始值,用它來初始化成員(C++11)

  • struct Person
    {
      string name = 'mango';  //類內(nèi)初始化,vs2010不支持此C++11新特性
          int age = 26; //類內(nèi)初始化,vs2010不支持此C++11新特性
    }
    
  • 否則,默認(rèn)初始化該成員

    • 如果是內(nèi)置類型,定義于任何函數(shù)體之外的變量被初始化為0;定義在函數(shù)體內(nèi)部的不被初始化
    • 每個(gè)類調(diào)用默認(rèn)初始化

7.11-1.13 練習(xí)

為Sales_data添加構(gòu)造函數(shù),并用istream構(gòu)造函數(shù)重寫229頁程序。

#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <iostream>
#include <string>

struct Sales_data 
{
    //構(gòu)造函數(shù)
    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);
  
    //成員函數(shù)
    //獲得isbn編號(hào)
    std::string isbn() const
    {
        return this->bookNo;
    }
    Sales_data& combine(const Sales_data&);
    double avg_price() const;

    //數(shù)據(jù)成員
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};

//非成員函數(shù)聲明
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 代表本身
}

//對(duì)未定義的成員函數(shù)在類外進(jìn)行定義
double Sales_data::avg_price() const
{
    if (units_sold)
    {
        return revenue/units_sold;
    }
    else
    {
        return 0;
    }
}

//定義一個(gè)返回this對(duì)象的函數(shù)
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
    this->units_sold += rhs.units_sold;
    this->revenue += rhs.revenue;
    return *this; //返回調(diào)用該函數(shù)的對(duì)象
}

//對(duì)非成員函數(shù)定義
std::istream& read(std::istream &is, Sales_data &item)
{
    double price = 0;
    //輸入isbn編號(hào), 賣出數(shù)量, 單價(jià)
    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的數(shù)據(jù)成員拷貝給sum
    //默認(rèn)情況下,拷貝類的對(duì)象其實(shí)拷貝的是對(duì)象的數(shù)據(jù)成員
    Sales_data sum = lhs; 
    sum.combine(rhs);
    return sum;
}
#endif

訪問控制和封裝

引入public 和private的關(guān)鍵詞。

//Sales.data.h添加訪問控制,函數(shù)實(shí)現(xiàn)不變。
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;
};

友元

類可以允許友元類和友元函數(shù)訪問它的私有成員。

//Sales.data.h添加友元函數(shù)
class Sales_data 
{
  //友元聲明,不代表普通聲明,函數(shù)需要聲明仍需要在類外進(jìn)行聲明
    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;
};
//非成員函數(shù)聲明
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 練習(xí)

class Person
{
private:
    std::string name;
    std::string address;
public:
    std::string getName() const
    {
        return this->name;
    }
    std::string getAddress() const{
        return this->address;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文博客園地址:http://www.cnblogs.com/xiongxuanwen/p/4290086.htm...
    先之閱讀 957評(píng)論 0 5
  • C++文件 例:從文件income. in中讀入收入直到文件結(jié)束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 3,092評(píng)論 0 3
  • 6日,第一次乘飛機(jī)出游,內(nèi)心還有點(diǎn)小激動(dòng)。天上的風(fēng)景確實(shí)好,最愛這種漸變的藍(lán),在遠(yuǎn)處的交際線匯成一道白。云層下面便...
    行走的大獅子閱讀 232評(píng)論 2 3
  • 深圳這個(gè)冬日到目前為止持續(xù)多天的暖陽高照,干燥得不像一個(gè)季風(fēng)氣候的海邊城市。 我的皮膚,是那種沙漠肌與嬰兒肌的混合...
    魚頭shiny閱讀 1,540評(píng)論 1 3
  • 2018.08.11 印象筆記 第一章 建立思維的秩序 1.1記錄的目的是為了遺忘 1.1.1大腦擅長思考而不是記...
    小馬成功過河閱讀 274評(píng)論 0 0

友情鏈接更多精彩內(nèi)容