CPP_Basic_Code_P12.1-PP12.10.4

//  The Notes Created by Z-Tech on 2017/2/17.
//  All Codes Boot on 《C++ Primer Plus》V6.0
//  OS:MacOS 10.12.4
//  Translater:clang/llvm8.0.0 &g++4.2.1
//  Editer:iTerm 2&Sublime text 3
//  IDE: Xcode8.2.1&Clion2017.1

//P12.1-P12.3
Z_Head.h
#ifndef XXX_H
#define XXX_H

#include <iostream>

class StringBad
{

private:
    char * str;
    int len;
    static int num_strings;

public:
    StringBad(const char * s);
    StringBad();
    ~StringBad();

    friend std::ostream &operator<<(std::ostream & os,const StringBad & st);
};

#endif

SubFunctions.cpp
#include "Z_Head.h"
#include <cstring>
using std::cout;

int StringBad::num_strings=0;

StringBad::StringBad(const char * s)
{
    len = std::strlen(s);
    str = new char[len+1];
    std::strcpy(str,s);
    num_strings++;
    cout<<num_strings<<": \""<<str<<"\" object created\n";
}

StringBad::StringBad()
{
    len = 4;
    str = new char[len];
    std::strcpy(str,"C++");
    num_strings++;
    cout<<num_strings<<": \""<<str<<"\" default object created\n";
}

StringBad::~StringBad()
{
    cout<<"\""<<str<<"\" object deleted, ";
    --num_strings;
    cout<<num_strings<<" left\n";
    delete [] str;
}

std::ostream &operator<<(std::ostream & os,const StringBad & st)
{
    os<<st.str;
    return os;
}

Main.cpp
#include "Z_Head.h"
using std::cout;

void callme1(StringBad & );
void callme2(StringBad);

int main()
{
    using std::endl;
    {
        cout<<"String an inner block.\n";
        StringBad headline1("Celery Stalks at Midnight");
        StringBad headline2("Lettuce Prey");
        StringBad sports("Spinach Leaves Bowl for Dollars");

        cout<<"headline1: "<<headline1<<endl;
        cout<<"headline2: "<<headline2<<endl;
        cout<<"sports: "<<sports<<endl;

        callme1(headline1);
        cout<<"headline1: "<<headline1<<endl;

        callme2(headline2);//Bug出處
        cout<<"headline2: "<<headline2<<endl;

        cout<<"Initialize one object to another:\n";
        StringBad sailor = sports;
        cout<<"sailor: "<<sailor<<endl;

        cout<<"Assign one object to another:\n";
        StringBad knot;
        knot = headline1;
        cout<<"knot: "<<knot<<endl;
        cout<<"Exiting the block.\n";
    }
    cout<<"End of main()\n";

    return 0;
}

void callme1(StringBad & rsb)
{
    cout<<"String passed by reference:\n";
    cout<<"     \""<<rsb<<"\"\n";
}

void callme2(StringBad sb)
{
    cout<<"String passed by value:\n";
    cout<<"     \""<<sb<<"\"\n";
}

//P12.4-P12.6
Z_Head.h
#ifndef XXX_H
#define XXX_H

#include <iostream>
using std::ostream;
using std::istream;

class String
{

private:
    char * str;
    int len;
    static int num_strings;//聲明靜態(tài)數(shù)據(jù)成員,但此處無法定義
    static const int CINLIM = 80;//靜態(tài)常量可以初始化

public:
    //構(gòu)造函數(shù)和方法
    String(const char * s);
    String();
    String(const String &);
    ~String();
    int length() const {return len;}//內(nèi)聯(lián)函數(shù)
    //操作符重載成員函數(shù)
    String & operator=(const String &);
    String & operator=(const char *);
    char & operator[](int i);
    const char & operator[](int i) const;//const版本
    //操作符重載友元函數(shù)
    friend bool operator<(const String &st1,const String &st2);
    friend bool operator>(const String &st1,const String &st2);
    friend bool operator==(const String &st1,const String & st2);
    friend ostream & operator<<(ostream & os,const String & st);
    friend istream & operator>>(istream & is,String & st);
    //靜態(tài)類成員函數(shù)
    static int HowMany();
};

#endif

SubFunctions.cpp
#include "Z_Head.h"
#include <cstring>
using std::cout;
using std::cin;

int String::num_strings=0;

//靜態(tài)類成員函數(shù)
int String::HowMany()
{
    return num_strings;//統(tǒng)計對象創(chuàng)建的次數(shù)
}

//構(gòu)造函數(shù)和方法
String::String(const char * s)//指針版本創(chuàng)建對象
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str,s);
    num_strings++;
}

String::String()//默認參數(shù)創(chuàng)建
{
    len = 4;
    str = new char[1];
    str[0] = '\0';
    num_strings++;
}

String::String(const String & st)//引用對象創(chuàng)建對象
{
    num_strings++;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str,st.str);
}

String::~String()//析構(gòu)函數(shù)
{
    --num_strings;
    delete [] str;
}

//操作符重載成員函數(shù)
String & String::operator=(const String & st)//重載使用引用對象的賦值
{
    if (this == &st)
        return *this;
    delete [] str;//釋放指針指向內(nèi)存
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str,st.str);
    return *this;
}

String & String::operator=(const char * s)//重載使用字符串指針的賦值
{
    delete [] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str,s);
    return *this;
}

char & String::operator[](int i)//重載對象數(shù)組的引用
{
    return str[i];
}

const char & String::operator[](int i) const//重載常量版本
{
    return str[i];
}

//操作符重載友元函數(shù)
bool operator<(const String &st1,const String &st2)//重載對象字符串排序<
{
    return (std::strcmp(st1.str,st2.str)<0);//st1在st2前則返回負數(shù)
}

bool operator>(const String &st1,const String &st2)//重載對象字符串排序>
{
    return (st2.str<st1.str);//巧妙利用前者
}

bool operator==(const String &st1,const String & st2)//重載對象字符串排序==
{
    return (std::strcmp(st1.str,st2.str)==0);
}

ostream & operator<<(ostream & os,const String & st)//重載對象的輸出流
{
    os<<st.str;
    return os;
}

istream & operator>>(istream & is,String & st)//重載對象的輸入流
{
    char temp[String::CINLIM];
    is.get(temp,String::CINLIM);
    if (is)
        st=temp;
    while (is && is.get()!='\n')
        continue;
    return is;
}

Main.cpp
#include "Z_Head.h"
const int ArSize = 10;
const int MaxLen = 81;


int main()
{
    using std::cout;
    using std::cin;
    using std::endl;

    String name;
    cout<<"Hi,what's your name?\n>> ";
    cin>>name;//讀取姓名到name

    cout<<name<<",please enter up to "<<ArSize
        <<" short saying <empty line to quit>:\n";
    String saying[ArSize];//創(chuàng)建對象數(shù)組
    char temp[MaxLen];//臨時字符串?dāng)?shù)組
    int i;
    for (i = 0;i < ArSize;i++)
    {
        cout<<i+1<<": ";
        cin.get(temp,MaxLen);//讀取諺語到temp
        while (cin && cin.get()!='\n')//讀取成功且不到結(jié)尾則繼續(xù)
            continue;
        if (!cin||temp[0]=='\0')//讀取失敗或者碰到字符串結(jié)尾\0則彈出
            break;
        else
            saying[i]=temp;//將讀取的temp存入saying對象數(shù)組
    }
    int total = i;
    if (total > 0)//如果確實讀取成功了
    {
        cout<<"Here are your saying:\n";
        for (i = 0;i < total;i++)
            cout<<saying[i][0]<<": "<<saying[i]<<endl;

        int shortest = 0;
        int first = 0;
        for (i = 1;i < total;i++)
        {
            if (saying[i].length() < saying[shortest].length())//字符串長度
                shortest = i;//i已被設(shè)置為第一個諺語
            if (saying[i] < saying[first])//誰小就在前膀估,并被賦值到first
                first = i;
        }
        cout<<"Shortest saying :\n"<<saying[shortest]<<endl;
        cout<<"First alphabetically:\n"<<saying[first]<<endl;
        cout<<"This program used "<<String::HowMany()//統(tǒng)計被創(chuàng)建的對象數(shù)
            <<" String objects.Bye.\n";
    }
    else
        cout<<"No input!Bye.\n";
    return  0;
}

//P12.7
//配合P12.4-P12.5
const int ArSize = 10;
const int MaxLen = 81;

int main()
{
    using namespace std;
    String name;
    cout<<"Hi,What's your name?\n>>";
    cin>>name;

    cout<<name<<",Please enter up to "<<ArSize
        <<" short saying <empty line to quit>:\n";
    String saying[ArSize];
    char temp[MaxLen];
    int i;
    for (i = 0;i < ArSize;i++)
    {
        cout<<i+1<<": ";
        cin.get(temp,MaxLen);
        while (cin&&cin.get()!='\n')
            continue;
        if (!cin||temp[0]=='\0')
            break;
        else
            saying[i]=temp;
    }
    int total = i;
    if (total > 0)
    {
        cout<<"Here are your saying:\n";
        for (i = 0;i < total;i++)
            cout<<saying[i]<<'\n';

        String * shortest = &saying[0];
        String * first = &saying[0];
        for (i = 1;i < total;i++)
        {
            if (saying[i].length() < shortest->length())//注意長度比較
                shortest = &saying[i];
            if (saying[i] < *first)
                first = &saying[i];
        }
        cout<<"Shortest saying:\n"<< * shortest<<endl;
        cout<<"First saying:\n"<< * first<<endl;
        srand(time(0));
        int choice = rand() % total;
        String * favorite = new String(saying[choice]);
        cout<<"My favorite saying:\n"<< *favorite<<endl;
        delete favorite;
    }
    else
        cout<<"Not much to say, eh?\n";
    cout<<"Bye.\n";
    return 0;
}


//P12.8
#include <iostream>

using namespace std;
const int BUF = 512;

class JustTesting
{
private:
    string words;
    int number;
public:
    JustTesting(const string &s = "Just Testing", int n = 0)
    {
        words = s;
        number = n;
        cout << words << " constructed\n";
    }

    ~JustTesting()
    { cout << words << " destroyed"; }

    void Show() const
    { cout << words << ", " << number << endl; }
};

int main()
{
    char *buffer = new char[BUF];

    JustTesting *pc1,*pc2;

    pc1=new (buffer) JustTesting;
    pc2=new JustTesting("Heap1",20);

    cout<<"Memory block addresses:\n"<<"buffer:"
        <<(void *)buffer<<"    heap: "<<pc2<<endl;
    cout<<"Memory contents:\n";
    cout<<pc1<<": ";
    pc1->Show();
    cout<<pc2<<": ";
    pc2->Show();

    JustTesting *pc3,*pc4;
    pc3=new (buffer) JustTesting("Bad Idea",6);//這會導(dǎo)致緩沖池被覆蓋
    pc4=new JustTesting("Heap2",10);//每次都會在堆里分配新的地址

    cout<<"Memory addresses:\n";
    cout<<pc3<<": ";
    pc3->Show();
    cout<<pc4<<": ";
    pc4->Show();

    delete pc2;
    delete pc4;
    delete [] buffer;
    cout<<"Done.\n";
    return 0;
}


//P12.9
#include <iostream>

using namespace std;
const int BUF = 512;

class JustTesting
{
private:
    string words;
    int number;
public:
    JustTesting(const string &s = "Just Testing", int n = 0)
    {
        words = s;
        number = n;
        cout << words << " constructed\n";
    }

    ~JustTesting()
    { cout << words << " destroyed\n"; }

    void Show() const
    { cout << words << ", " << number << endl; }
};


int main()
{
    char *buffer = new char[BUF];

    JustTesting *pc1, *pc2;

    pc1 = new(buffer) JustTesting;
    pc2 = new JustTesting("Heap1", 20);

    cout << "Memory block addresses:\n" << "buffer:"
         << (void *) buffer << "    heap: " << pc2 << endl;
    cout << "Memory contents:\n";
    cout << pc1 << ": ";
    pc1->Show();
    cout << pc2 << ": ";
    pc2->Show();

    JustTesting *pc3, *pc4;
    pc3 = new(buffer + sizeof(JustTesting)) JustTesting("Better Idea", 6);//右移1個對象的空間
    pc4 = new JustTesting("Heap2", 10);//每次都會在堆里分配新的地址

    cout << "Memory addresses:\n";
    cout << pc3 << ": ";
    pc3->Show();
    cout << pc4 << ": ";
    pc4->Show();

    delete pc2;
    delete pc4;
    pc3->~JustTesting();//刪除指向的對象
    pc1->~JustTesting();
    delete[] buffer;
    cout << "Done.\n";
    return 0;
}

//P12.10-12.12
Z_Head.h
#ifndef QUEUE_H
#define QUEUE_H

class Customer
{
private:
    long arrive;
    int processtime;
public:
    Customer() { arrive = processtime = 0; }//構(gòu)造函數(shù)

    void set(long when);//設(shè)置隨機服務(wù)時長和抵達時間

    long when() const { return arrive; }//返回到達時間

    int ptime() const { return processtime; }//返回服務(wù)時長
};

typedef Customer Item;//將類名Customer簡化為替換為Item

class Queue
{
private:
    struct Node { Item item;struct Node *next; };//創(chuàng)建節(jié)點結(jié)構(gòu)
    enum { Q_SIZE = 10 };//類內(nèi)常量
    Node *front;
    Node *rear;
    int items;
    const int qsize;

    Queue(const Queue &q) : qsize(0) {}//偽私有方法防止意外創(chuàng)建

    Queue &operator=(const Queue &q) { return *this; }//防止意外

public:
    Queue(int qs = Q_SIZE);

    ~Queue();

    bool isempty() const;

    bool isfull() const;

    int queuecount() const;//隊列成員計數(shù)

    bool enqueue(const Item &item);//加入隊尾

    bool dequeue(Item &item);//離開隊首
};

#endif

SubFunctions.cpp
#include "Z_Head.h"
#include <cstdlib>

Queue::Queue(int qs) : qsize(qs)//成員初始化列表
{
    front = rear = nullptr;
    items = 0;
}

Queue::~Queue()
{
    Node *temp;
    while (front != nullptr)
    {
        temp = front;//暫時保存指針
        front = front->next;//后置指針前移
        delete temp;//刪除原front
    }
}

bool Queue::isempty() const
{
    return items == 0;
}

bool Queue::isfull() const
{
    return items == qsize;
}

int Queue::queuecount() const
{
    return items;
}

bool Queue::enqueue(const Item &item)
{
    if (isfull())
        return false;
    Node *add = new Node;
    add->item = item;
    add->next = nullptr;
    items++;
    if (front == nullptr)
        front = add;
    else
        rear->next = add;
    rear = add;
    return true;
}

bool Queue::dequeue(Item &item)
{
    if (front == nullptr)//isempty()
        return false;
    item = front->item;//將第一個對象節(jié)點的數(shù)據(jù)傳給引用
    items--;
    Node *temp = front;
    front = front->next;//后一個指針設(shè)為前一個
    delete temp;//刪除節(jié)點
    if (items == 0)
        rear = nullptr;//如果移除后隊列空則設(shè)尾部為空指針
    return true;
}

void Customer::set(long when)
{
    processtime = std::rand() % 3 + 1;//rand()需要srand()作為種子
    arrive = when;
}

Main.cpp
#include "Z_Head.h"
#include <iostream>

const int MIN_PER_HR = 60;

bool newcustomer(double x);

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    using std::ios_base;

    std::srand(std::time(0));

    cout << "Case Study: Bank of Heather Automatic Teller\n";
    cout << "Enter Maximum size of queue: ";
    int qs;
    cin >> qs;
    cin.get();
    Queue line(qs);//創(chuàng)建qs人的隊列

    cout << "Enter number of simulation hours: ";//模仿小時數(shù)
    int hours;
    cin >> hours;
    cin.get();
    long cyclelimit = MIN_PER_HR * hours;

    cout << "Enter the average number of customers per hour: ";
    double perhour;
    cin >> perhour;
    cin.get();
    double min_per_cust;
    min_per_cust = MIN_PER_HR;

    Item temp;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time = 0;
    long line_wait = 0;

    for (int cycle = 0; cycle < cyclelimit; cycle++)
    {
        if (newcustomer(min_per_cust))
        {
            if (line.isfull())
                turnaways++;
            else
            {
                customers++;
                temp.set(cycle);
                line.enqueue(temp);
            }
        }
        if (wait_time <= 0 && !line.isempty())
        {
            line.dequeue(temp);
            wait_time = temp.ptime();
            line_wait += cycle - temp.when();
            served++;
        }
        if (wait_time > 0)
            wait_time--;
        sum_line += line.queuecount();
    }

    if (customers > 0)
    {
        cout << "customers acceted: " << customers << endl;
        cout << " customers served: " << served << endl;
        cout << "        turnaways: " << turnaways << endl;
        cout << " average queue size: ";
        cout.precision(2);
        cout.setf(ios_base::fixed, ios_base::floatfield);
        cout << double(sum_line / cyclelimit) << endl;
        cout << " average wait time: " << double(line_wait / served) << " minutes\n";
    } else
        cout << "No customers!\n";
    cout << "Done!\n";

    return 0;
}

bool newcustomer(double x)
{
    return (std::rand() * x / RAND_MAX < 1);
}


//PP12.10.1
#include <cstring>
#include <iostream>

class Cow
{
    //隱式默認private
    char name[20];
    char *hobby;
    double weight;
public:
    Cow();

    Cow(const char *nm, const char *ho, double wt);

    Cow(const Cow &c);

    ~Cow();

    Cow &operator=(const Cow &c);

    void showCow() const;
};

Cow::Cow()
{
    name[0] = '\0';
    hobby = nullptr;
    weight = 0;
}

Cow::Cow(const char *nm, const char *ho, double wt)
{
    strcpy(name, nm);
    hobby = new char[strlen(ho) + 1];
    strcpy(hobby, ho);
    weight = wt;
}

Cow::Cow(const Cow &c)
{
    strcpy(name, c.name);
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby);
    weight = c.weight;
}

Cow::~Cow()
{
    delete[] hobby;
}

Cow &Cow::operator=(const Cow &c)
{
    strcpy(name, c.name);
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby);
    weight = c.weight;
    return *this;
}

void Cow::showCow() const
{
    std::cout << "Name: " << name << std::endl;
    std::cout << "Hobby: " << hobby << std::endl;
    std::cout << "Weight: " << weight << std::endl;
}

int main()
{
    Cow test1;

    Cow test2("楊旭舟", "Find my girl.", 120);
    test2.showCow();

    Cow test3(test2);
    test3.showCow();

    test1 = test2;
    test2.showCow();

    return 0;
}

//PP12.10.2
Z_Head.h
#include <iostream>
using std::ostream;
using std::istream;

class String
{

private:
    char *str;
    unsigned len;
    static int num_strings;//聲明靜態(tài)數(shù)據(jù)成員蹲缠,但此處無法定義
    static const int CINLIM = 80;//靜態(tài)常量可以初始化

public:
    //靜態(tài)類成員函數(shù)
    static int HowMany();

    //構(gòu)造函數(shù)和方法
    String(const char *s);

    String();

    String(const String &);

    ~String();

    int length() const { return len; }//內(nèi)聯(lián)函數(shù)

    void Stringlow();

    void Stringup();

    unsigned Has(char ch) const;

    //操作符重載成員函數(shù)
    String &operator=(const String &);

    String &operator=(const char *);

    String &operator+=(const String &);

    char &operator[](int i);

    const char &operator[](int i) const;//const版本

    //操作符重載友元函數(shù)
    friend bool operator<(const String &st1, const String &st2);

    friend bool operator>(const String &st1, const String &st2);

    friend String operator+(const String &st1, const String &st2);

    friend bool operator==(const String &st1, const String &st2);

    friend ostream &operator<<(ostream &os, const String &st);

    friend istream &operator>>(istream &is, String &st);
};

SubFunctions.cpp
#include "Z_Head.h"
#include <cstring>

using std::cout;
using std::cin;

int String::num_strings = 0;

//靜態(tài)類成員函數(shù)
int String::HowMany()
{
    return num_strings;//統(tǒng)計對象創(chuàng)建的次數(shù)
}

//構(gòu)造函數(shù)和方法
String::String(const char *s)//指針版本創(chuàng)建對象
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    num_strings++;
}

String::String()//默認參數(shù)創(chuàng)建
{
    len = 4;
    str = new char[1];
    str[0] = '\0';
    num_strings++;
}

String::String(const String &st)//引用對象創(chuàng)建對象
{
    num_strings++;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
}

String::~String()//析構(gòu)函數(shù)
{
    --num_strings;
    delete[] str;
}

void String::Stringlow()
{
    for (unsigned i=0;i<len;i++)
        str[i]=(char)tolower((int)str[i]);
}

void String::Stringup()
{
    for (unsigned i=0;i<len;i++)
        str[i]=(char)toupper((int)str[i]);
}

unsigned String::Has(char ch) const
{
    unsigned counter=0;
    for (unsigned i=0;i<len;i++)
        if (str[i]==ch)//不需要'ch'
            counter++;
    return counter;
}

//操作符重載成員函數(shù)
String &String::operator=(const String &st)//重載使用引用對象的賦值
{
    if (this == &st)
        return *this;
    delete[] str;//釋放指針指向內(nèi)存
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}

String &String::operator=(const char *s)//重載使用字符串指針的賦值
{
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}

String &String::operator+=(const String &st)
{
    return (*this += st);//利用cstring追加字符串
}

char &String::operator[](int i)//重載對象數(shù)組的引用
{
    return str[i];
}

const char &String::operator[](int i) const//重載常量版本
{
    return str[i];
}

//操作符重載友元函數(shù)
bool operator<(const String &st1, const String &st2)//重載對象字符串排序<
{
    return (std::strcmp(st1.str, st2.str) < 0);//st1在st2前則返回負數(shù)
}

bool operator>(const String &st1, const String &st2)//重載對象字符串排序>
{
    return (st2.str < st1.str);//巧妙利用前者
}

String operator+(const String &st1, const String &st2)
{
    char * temp=new char[st1.len+st2.len+1];//獲取和長度
    strcpy(temp,st1.str);//復(fù)制第一部分
    strcat(temp,st2.str);//添加第二部分
    String tmp(temp);//調(diào)用構(gòu)造函數(shù)生成臨時String對象
    delete [] temp;//清空temp內(nèi)存
    return tmp;//返回對象
}

bool operator==(const String &st1, const String &st2)//重載對象字符串排序==
{
    return (std::strcmp(st1.str, st2.str) == 0);
}

ostream &operator<<(ostream &os, const String &st)//重載對象的輸出流
{
    os << st.str;
    return os;
}

istream &operator>>(istream &is, String &st)//重載對象的輸入流
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
        st = temp;
    while (is && is.get() != '\n')
        continue;
    return is;
}

Main.cpp
#include "Z_Head.h"

using namespace std;

int main()
{
    String s1(" and I am a C++ student.");
    String s2="Please enter your name: ";
    String s3;
    cout<<s2;
    cin>>s3;
    s2="My name is "+s3;
    cout<<s2<<".\n";
    s2+=s1;
    s2.Stringup();
    cout<<"The string\n"<<s2<<"\ncontains "
        <<s2.Has('A')<<" 'A'characters in it.\n";
    s1="red";
    String rgb[3]={String(s1),String("green"),String("blue")};
    cout<<"Enter the name of a primary color for mixing light: ";
    String ans;
    bool success= false;
    while (cin>>ans)
    {
        ans.Stringlow();
        for (int i=0;i<3;i++)
        {
            if (ans==rgb[i])
            {
                cout<<"That's right!\n";
                success=true;
                break;
            }
        }
        if (success)
            break;
        else
            cout<<"Try again!\n";
    }
    cout<<"Bye.\n";
    return 0;
}

//PP12.10.3
Z_Head.h
#include <string>
#include <iostream>

class Stock
{
private:
    char *company;
    long shares;
    double share_val;
    double total_val;

    void set_tot()
    { total_val = shares * share_val; }

public:
    Stock();

    Stock(const char *co, long n = 0, double pr = 0);

    ~Stock();

    void buy(long num, double price);

    void sell(long num, double price);

    void update(double price);

    friend std::ostream &operator<<(std::ostream & os,const Stock & st);

    const Stock &topval(const Stock &s) const;
};

SubFunctions.cpp
#include <iostream>
Stock::Stock()
{
    company = nullptr;
    shares = 0;
    share_val = 0.0;
    total_val = 0.0;
}

Stock::Stock(const char *co, long n, double pr)
{
    company = new char[strlen(co) + 1];
    strcpy(company, co);

    if (n < 0)
    {
        std::cout << "Number of shares can't be negative; "
                  << company << " shares set to 0.\n";
        shares = 0;
    } else
        shares = n;
    share_val = pr;
    set_tot();
}

Stock::~Stock()//析構(gòu)函數(shù)
{
    delete[] company;
}

void Stock::buy(long num, double price)
{
    if (num < 0)
    {
        std::cout << "Number of shares can't be negative. "
                  << "Transaction is aborted.\n";
    } else
    {
        shares += num;
        share_val = price;
        set_tot();
    }

}

void Stock::sell(long num, double price)
{
    using std::cout;
    if (num < 0)
    {
        cout << "Number of shares can't be negative. "
             << "Transaction is aborted.\n";
    } else if (num > shares)
    {
        cout << "Number of shares can't be negative. "
             << "Transaction is aborted.\n";
    } else
    {
        shares -= num;
        share_val = price;
        set_tot();
    }
}

void Stock::update(double price)
{
    share_val = price;
    set_tot();
}

std::ostream &operator<<(std::ostream &os, const Stock &st)//友元無后置const無需friend無需類限定
{
    using std::cout;
    using std::ios_base;
    ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);
    std::streamsize prec = cout.precision(3);
    os << "Company: " << st.company << " Shares: " << st.shares << '\n'
       << " Shares Price: $" << st.share_val;
    os.precision(2);
    os << " Total Worth: $" << st.total_val << '\n';

    os.setf(orig, ios_base::floatfield);
    os.precision(prec);
    return os;
}


const Stock &Stock::topval(const Stock &s) const
{
    if (s.total_val > total_val)
        return s;
    else
        return *this;//this指針揍魂,指向本對象
}

Main.cpp
const int STKS = 4;

int main()
{
    Stock stocks[STKS]
            {
                    Stock("NanoSmart", 12, 20.0),
                    Stock("Boffo Objects", 200, 2.0),
                    Stock("Monolithic Oblisks", 130, 3.25),
                    Stock("Fleep Enterprises", 60, 6.5)
            };
    std::cout << "Stock holding:\n";
    int st;
    for (st = 0; st < STKS; st++)
        std::cout << stocks[st];

    const Stock *top = &stocks[0];
    for (st = 1; st < STKS; st++)
        top = &top->topval(stocks[st]);//難點赐俗,對引用對象再次取地址就是指針!!挎峦!
    std::cout << "\nMost valuable holding:\n";
    std::cout << *top;//此處top需解除引用
    return 0;
}

//PP12.10.4
Z_Head.h
#include <iostream>

typedef unsigned long Item;

class Stack
{
private:
    enum { MAX = 10 };
    Item *pitems;
    int size;
    int top;
public:
    Stack(int n = MAX);

    Stack(const Stack &st);

    ~Stack();

    bool isempty() const;

    bool isfull() const;

    bool push(const Item &item);

    bool pop(Item &item);

    Stack &operator=(const Stack &st);

    friend std::ostream&operator<<(std::ostream & os,const Stack & st);
};

SubFunctions.cpp
Stack::Stack(int n)
{
    pitems = new Item[MAX];
    top = 0;
    size = 0;
}

Stack::Stack(const Stack &st)
{
    pitems = new Item[st.size];
    top = 0;
    size = 0;
    for (int i = 0; i < st.size; i++)
    {
        pitems[i] = st.pitems[i];//分別賦值
        size++;//調(diào)整到合適位置
        top++;
    }
}

Stack::~Stack()
{
    delete[] pitems;
}

bool Stack::isempty() const
{
    return top == 0;
}

bool Stack::isfull() const
{
    return top == MAX;
}

bool Stack::push(const Item &item)
{
    if (top < MAX)
    {
        pitems[top++] = item;
        size++;
        return true;
    } else
        return false;
}

bool Stack::pop(Item &item)
{
    if (top > 0)
    {
        item = pitems[top--];
        size--;
        return true;
    } else
        return false;
}

Stack &Stack::operator=(const Stack &st)
{
    delete [] pitems;
    pitems=new Item[st.size];
    top=0;
    size=0;
    for (int i = 0; i < st.size; i++)
    {
        pitems[i] = st.pitems[i];//分別賦值
        size++;//調(diào)整到合適位置
        top++;
    }
    return *this;
}

std::ostream&operator<<(std::ostream & os,const Stack & st)
{
    os<<"This stack is : "<<std::endl;
    int len=st.top-1;
    while (len!=-1)
    {
        os<<st.pitems[len]<<std::endl;
        len--;
    }
    return os;
}

Main.cpp
#include <iostream>

int main()
{
    using std::cout;
    Stack fuck;
    Item you[20] = {0};
    for (int i = 0; i < 11; i++)
    {
        you[i] = i + 1;
        fuck.push(you[i]);
    }

    cout << fuck;

    Stack s1(fuck);
    cout << s1;

    Stack s2 = fuck;
    cout << fuck;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市合瓢,隨后出現(xiàn)的幾起案子坦胶,更是在濱河造成了極大的恐慌,老刑警劉巖晴楔,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顿苇,死亡現(xiàn)場離奇詭異,居然都是意外死亡滥崩,警方通過查閱死者的電腦和手機岖圈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钙皮,“玉大人蜂科,你說我怎么就攤上這事《烫酰” “怎么了导匣?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茸时。 經(jīng)常有香客問我贡定,道長,這世上最難降的妖魔是什么可都? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任缓待,我火速辦了婚禮,結(jié)果婚禮上渠牲,老公的妹妹穿的比我還像新娘旋炒。我一直安慰自己,他們只是感情好签杈,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布瘫镇。 她就那樣靜靜地躺著,像睡著了一般答姥。 火紅的嫁衣襯著肌膚如雪铣除。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天鹦付,我揣著相機與錄音尚粘,去河邊找鬼。 笑死敲长,一個胖子當(dāng)著我的面吹牛背苦,可吹牛的內(nèi)容都是我干的互捌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼行剂,長吁一口氣:“原來是場噩夢啊……” “哼秕噪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厚宰,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤腌巾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后铲觉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體澈蝙,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年撵幽,在試婚紗的時候發(fā)現(xiàn)自己被綠了灯荧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡盐杂,死狀恐怖逗载,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情链烈,我是刑警寧澤厉斟,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站强衡,受9級特大地震影響擦秽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜漩勤,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一感挥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧越败,春花似錦触幼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巨双。三九已至噪猾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筑累,已是汗流浹背袱蜡。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慢宗,地道東北人坪蚁。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓奔穿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親敏晤。 傳聞我的和親對象是個殘疾皇子贱田,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容