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;//声明静态数据成员,但此处无法定义
    static const int CINLIM = 80;//静态常量可以初始化

public:
    //构造函数和方法
    String(const char * s);
    String();
    String(const String &);
    ~String();
    int length() const {return len;}//内联函数
    //操作符重载成员函数
    String & operator=(const String &);
    String & operator=(const char *);
    char & operator[](int i);
    const char & operator[](int i) const;//const版本
    //操作符重载友元函数
    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);
    //静态类成员函数
    static int HowMany();
};

#endif

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

int String::num_strings=0;

//静态类成员函数
int String::HowMany()
{
    return num_strings;//统计对象创建的次数
}

//构造函数和方法
String::String(const char * s)//指针版本创建对象
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str,s);
    num_strings++;
}

String::String()//默认参数创建
{
    len = 4;
    str = new char[1];
    str[0] = '\0';
    num_strings++;
}

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

String::~String()//析构函数
{
    --num_strings;
    delete [] str;
}

//操作符重载成员函数
String & String::operator=(const String & st)//重载使用引用对象的赋值
{
    if (this == &st)
        return *this;
    delete [] str;//释放指针指向内存
    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)//重载对象数组的引用
{
    return str[i];
}

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

//操作符重载友元函数
bool operator<(const String &st1,const String &st2)//重载对象字符串排序<
{
    return (std::strcmp(st1.str,st2.str)<0);//st1在st2前则返回负数
}

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];//创建对象数组
    char temp[MaxLen];//临时字符串数组
    int i;
    for (i = 0;i < ArSize;i++)
    {
        cout<<i+1<<": ";
        cin.get(temp,MaxLen);//读取谚语到temp
        while (cin && cin.get()!='\n')//读取成功且不到结尾则继续
            continue;
        if (!cin||temp[0]=='\0')//读取失败或者碰到字符串结尾\0则弹出
            break;
        else
            saying[i]=temp;//将读取的temp存入saying对象数组
    }
    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已被设置为第一个谚语
            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()//统计被创建的对象数
            <<" 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);//这会导致缓冲池被覆盖
    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; }//构造函数

    void set(long when);//设置随机服务时长和抵达时间

    long when() const { return arrive; }//返回到达时间

    int ptime() const { return processtime; }//返回服务时长
};

typedef Customer Item;//将类名Customer简化为替换为Item

class Queue
{
private:
    struct Node { Item item;struct Node *next; };//创建节点结构
    enum { Q_SIZE = 10 };//类内常量
    Node *front;
    Node *rear;
    int items;
    const int qsize;

    Queue(const Queue &q) : qsize(0) {}//伪私有方法防止意外创建

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

public:
    Queue(int qs = Q_SIZE);

    ~Queue();

    bool isempty() const;

    bool isfull() const;

    int queuecount() const;//队列成员计数

    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;//将第一个对象节点的数据传给引用
    items--;
    Node *temp = front;
    front = front->next;//后一个指针设为前一个
    delete temp;//删除节点
    if (items == 0)
        rear = nullptr;//如果移除后队列空则设尾部为空指针
    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);//创建qs人的队列

    cout << "Enter number of simulation hours: ";//模仿小时数
    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;//声明静态数据成员,但此处无法定义
    static const int CINLIM = 80;//静态常量可以初始化

public:
    //静态类成员函数
    static int HowMany();

    //构造函数和方法
    String(const char *s);

    String();

    String(const String &);

    ~String();

    int length() const { return len; }//内联函数

    void Stringlow();

    void Stringup();

    unsigned Has(char ch) const;

    //操作符重载成员函数
    String &operator=(const String &);

    String &operator=(const char *);

    String &operator+=(const String &);

    char &operator[](int i);

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

    //操作符重载友元函数
    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;

//静态类成员函数
int String::HowMany()
{
    return num_strings;//统计对象创建的次数
}

//构造函数和方法
String::String(const char *s)//指针版本创建对象
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    num_strings++;
}

String::String()//默认参数创建
{
    len = 4;
    str = new char[1];
    str[0] = '\0';
    num_strings++;
}

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

String::~String()//析构函数
{
    --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;
}

//操作符重载成员函数
String &String::operator=(const String &st)//重载使用引用对象的赋值
{
    if (this == &st)
        return *this;
    delete[] str;//释放指针指向内存
    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)//重载对象数组的引用
{
    return str[i];
}

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

//操作符重载友元函数
bool operator<(const String &st1, const String &st2)//重载对象字符串排序<
{
    return (std::strcmp(st1.str, st2.str) < 0);//st1在st2前则返回负数
}

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);//复制第一部分
    strcat(temp,st2.str);//添加第二部分
    String tmp(temp);//调用构造函数生成临时String对象
    delete [] temp;//清空temp内存
    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()//析构函数
{
    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++;//调整到合适位置
        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++;//调整到合适位置
        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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容