C++ Prime Plus 学习笔记035

书籍:C++ Primer Plus (第六版)(中文版)

工具:Dev-C++ 5.11

电脑信息:Intel® Xeon® CPU E5-2603 v3 @ 1.60GHz

系统类型:64位操作系统,基于X64的处理器 windows10 专业版

第14章 C++中的代码重用

14.3 多重继承

实例14.4

之前编译失败,是因为没有析构函数。

workermi.h

workermi.cpp

cpp 复制代码
//Worker methods
Worker::~Worker()
{
 
}

workmi.cpp

编译运行结果:

cpp 复制代码
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
w
Enter waiter's name: wally fff
Enter worker's ID: 1040
Enter waiter's panache rating: 4
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
s
Enter singer's name: sinpad pa
Enter worker's ID: 1044
Enter number for singer's vocal range:
0: other    1: alto    2: contralto    3: soprano
4: bass    5: baritone    6: tenor
5
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
t
Enter singing waiter's name: naldafsfg f
Enter worker's ID: 1021
Enter waiter's panache rating: 6
Enter number for singer's vocal range:
0: other    1: alto    2: contralto    3: soprano
4: bass    5: baritone    6: tenor
3
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
q
Please enter a, w, s, t, or q: d
Please enter a, w, s, t, or q: q
Please enter a, w, s, t, or q: q
Please enter a, w, s, t, or q: q
Please enter a, w, s, t, or q: q
Please enter a, w, s, t, or q: Q
Please enter a, w, s, t, or q:

退不出来。

是因为

while (strchr("wstp", choice) == NULL)

写错了,应该时q,输入的时候习惯输入q,导致退不出来。

修改后再编译运行:

cpp 复制代码
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
w
Enter waiter's name: sfsgsg
Enter worker's ID: 1040
Enter waiter's panache rating: 4
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
s
Enter singer's name: dghdhj
Enter worker's ID: 1020
Enter number for singer's vocal range:
0: other    1: alto    2: contralto    3: soprano
4: bass    5: baritone    6: tenor
3
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
t
Enter singing waiter's name: ghfgj
Enter worker's ID: 1256
Enter waiter's panache rating: 3
Enter number for singer's vocal range:
0: other    1: alto    2: contralto    3: soprano
4: bass    5: baritone    6: tenor
6
Enter the employee category:
w: waiter s: singer t:singing waiter q:quit
q

Here is your staff:

Category: waiter
Name: sfsgsg
Employee ID: 1040
Panache rating: 4

Category: singer
Name: dghdhj
Employee ID: 1020
Vocal range:soprano

Category: singing waiter
Name: ghfgj
Employee ID: 1256
Vocal range:tenor
Panache rating: 3
Bye.
请按任意键继续. . .

14.4 类模板

实例14.5

stacktp.h

cpp 复制代码
// stacktp.h -- a stack template
#ifndef STACKTP_H_
#define STACKTP_H_

template <class Type>
class Stack
{
private:
    enum {MAX = 10};    // constant specific to class
    Type items[MAX];    // holds stack items
    int top;            // index for top stack item
public:
    Stack();
    bool isempty();
    bool isfull();
    bool push(const Type & item);   // add item to stack
    bool pop(Type & item);          // pop top into item
};

template <class Type>
Stack<Type>::Stack()
{
    top = 0;
}

template <class Type>
bool Stack<Type>::isempty()
{
    return top == 0;
}

template <class Type>
bool Stack<Type>::isfull()
{
    return top == MAX;
}

template <class Type>
bool Stack<Type>::push(const Type & item)
{
    if (top < MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}

template <class Type>
bool Stack<Type>::pop(Type & item)
{
    if (top > 0)
    {
        item = items[--top];
        return true;
    }
    else
        return false;
}

#endif // STACKTP_H_

stacktem.cpp

cpp 复制代码
// stacktem.cpp -- testing the template stack class
#include <iostream>
#include <string>
#include <cctype>
#include "stacktp.h"
using std::cin;
using std::cout;

int main()
{
    Stack<std::string> st;  // create an empty stack
    char ch;
    std::string po;
    cout << "Please enter A to add a purchase order.\n"
         << "P to process a PO, or Q to quit.\n";
    while (cin >> ch && std::toupper(ch) != 'Q')
    {
        while (cin.get() != '\n')
            continue;
        if (!std::isalpha(ch))
        {
            cout << '\a';
            continue;
        }
        switch (ch)
        {
            case 'A':
            case 'a':   cout << "Enter a PO number to add: ";
                        cin >> po;
                        if (st.isfull())
                            cout << "stack already full\n";
                        else
                            st.push(po);
                        break;
            case 'P':
            case 'p':   if (st.isempty())
                            cout << "stack already empty\n";
                        else {
                            st.pop(po);
                            cout << "PO #" << po << " popped\n";
                            break;
                        }
        }
        cout << "Please enter A to add a purchase order.\n"
             << "P to process a PO, or Q to quit.\n";
    }
    cout << "Bye\n";
    return 0;
}

编译运行结果:

cpp 复制代码
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
A
Enter a PO number to add: red911porsche
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
A
Enter a PO number to add: blueR8audi
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
A
Enter a PO number to add: silver747boeing
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
p
PO #silver747boeing popped
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
p
PO #blueR8audi popped
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
p
PO #red911porsche popped
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
p
stack already empty
Please enter A to add a purchase order.
P to process a PO, or Q to quit.
Q
Bye

--------------------------------
Process exited after 119.6 seconds with return value 0
请按任意键继续. . .

实例14.6

stcktp1.h

cpp 复制代码
// stcktp1.h -- modified Stack template
#ifndef STCKTP1_H_
#define STCKTP1_H_

template <class Type>
class Stack
{
private:
    enum {SIZE = 10};    // default size
    int stacksize;
    Type * items;       // holds stack items
    int top;            // index for top stack item
public:
    explicit Stack(int ss = SIZE);
    Stack(const Stack & st);
    ~Stack() { delete [] items; }
    bool isempty() { return top == 0; }
    bool isfull() { return top == stacksize; }
    bool push(const Type & item);   // add item to stack
    bool pop(Type & item);          // pop top into item
    Stack & operator=(const Stack & st);
};

template <class Type>
Stack<Type>::Stack(int ss) : stacksize(ss), top(0)
{
    items = new Type [stacksize];
}

template <class Type>
Stack<Type>::Stack(const Stack & st)
{
    stacksize = st.stacksize;
    top = st.top;
    items = new Type [stacksize];
    for (int i = 0; i < top; i++)
        items[i] = st.items[i];
}

template <class Type>
bool Stack<Type>::push(const Type & item)
{
    if (top < stacksize)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}

template <class Type>
bool Stack<Type>::pop(Type & item)
{
    if (top > 0)
    {
        item = items[--top];
        return true;
    }
    else
        return false;
}

template <class Type>
Stack<Type> & Stack<Type>::operator=(const Stack<Type> & st)
{
    if (this == &st)
        return *this;
    delete [] items;
    stacksize = st.stacksize;
    top = st.top;
    items = new Type [stacksize];
    for (int i = 0; i < top; i++)
        items[i] = st.items[i];
    return *this; 
}

#endif

stkoptr1.cpp

cpp 复制代码
// stkoptr1.cpp -- testing stack of pointers
#include <iostream>
#include <cstdlib>     // for rand(), srand()
#include <ctime>       // for time()
#include "stcktp1.h"
const int Num = 10;
int main()
{
    std::srand(std::time(0)); // randomize rand()
    std::cout << "Please enter stack size: ";
    int stacksize;
    std::cin >> stacksize;
// create an empty stack with stacksize slots
    Stack<const char *> st(stacksize); 

// in basket
    const char * in[Num] = {
            " 1: Hank Gilgamesh", " 2: Kiki Ishtar",
            " 3: Betty Rocker", " 4: Ian Flagranti",
            " 5: Wolfgang Kibble", " 6: Portia Koop",
            " 7: Joy Almondo", " 8: Xaverie Paprika",
            " 9: Juan Moore", "10: Misha Mache"
            };
 // out basket
    const char * out[Num];

    int processed = 0;
    int nextin = 0;
    while (processed < Num)
    {
        if (st.isempty())
            st.push(in[nextin++]);
        else if (st.isfull())
            st.pop(out[processed++]);
        else if (std::rand() % 2  && nextin < Num)   // 50-50 chance
            st.push(in[nextin++]);
        else
            st.pop(out[processed++]);
    }
    for (int i = 0; i < Num; i++)
        std::cout << out[i] << std::endl;

    std::cout << "Bye\n";
    // std::cin.get();
    // std::cin.get();
	return 0; 
}

编译运行结果:

cpp 复制代码
Please enter stack size: 5
 1: Hank Gilgamesh
 2: Kiki Ishtar
 4: Ian Flagranti
 5: Wolfgang Kibble
 3: Betty Rocker
 8: Xaverie Paprika
 7: Joy Almondo
 9: Juan Moore
 6: Portia Koop
10: Misha Mache
Bye

--------------------------------
Process exited after 9.639 seconds with return value 0
请按任意键继续. . .

实例14.7

arraytp.h

cpp 复制代码
//arraytp.h  -- Array Template

#ifndef ARRAYTP_H
#define ARRAYTP_H

#include <iostream>
#include <cstdlib>

template <class T, int n>   // T为类型参数,n为int类型(非类型/表达式参数)
class ArrayTP
{
private:
    T ar[n];
public:
    ArrayTP() {};
    explicit ArrayTP(const T & v);
    virtual T & operator[](int i);
    virtual T operator[](int i) const;
};

template <class T, int n>
ArrayTP<T,n>::ArrayTP(const T & v)
{
    for (int i = 0; i < n; i++)
        ar[i] = v;
}

template <class T, int n>
T & ArrayTP<T,n>::operator[](int i)
{
    if (i < 0 || i >= n)
    {
        std::cerr << "Error in array limits: " << i
                  << " is out of range\n";
        std::exit(EXIT_FAILURE);
    }
    return ar[i];
}

template <class T, int n>
T ArrayTP<T,n>::operator[](int i) const
{
    if (i < 0 || i >= n)
    {
        std::cerr << "Error in array limits: " << i
                  << " is out of range\n";
        std::exit(EXIT_FAILURE);
    }
    return ar[i];
}

#endif 

twod.cpp

cpp 复制代码
// twod.cpp -- making a 2-d array
#include <iostream>
#include "arraytp.h"

int main(void)
{
    using std::cout;
    using std::endl;
    ArrayTP<int, 10> sums;
    ArrayTP<double, 10> aves;
    ArrayTP< ArrayTP<int,5>, 10> twodee;

    int i, j;

    for (i = 0; i < 10; i++)
    {
        sums[i] = 0;
        for (j = 0; j < 5; j++)
        {
            twodee[i][j] = (i + 1) * (j + 1);
            sums[i] += twodee[i][j];
        }
        aves[i] = (double) sums[i] / 10;
    }

    for (i = 0; i < 10; i++)
    {
        for (j = 0; j < 5; j++)
        {
            cout.width(2);
            cout << twodee[i][j] << ' ';
        }
        cout << ": sum = ";
        cout.width(3);
        cout  << sums[i] << ", average = " << aves[i] << endl;
    }

    cout << "Done.\n";

    return 0;
}

编译运行结果:

cpp 复制代码
 1  2  3  4  5 : sum =  15, average = 1.5
 2  4  6  8 10 : sum =  30, average = 3
 3  6  9 12 15 : sum =  45, average = 4.5
 4  8 12 16 20 : sum =  60, average = 6
 5 10 15 20 25 : sum =  75, average = 7.5
 6 12 18 24 30 : sum =  90, average = 9
 7 14 21 28 35 : sum = 105, average = 10.5
 8 16 24 32 40 : sum = 120, average = 12
 9 18 27 36 45 : sum = 135, average = 13.5
10 20 30 40 50 : sum = 150, average = 15
Done.

--------------------------------
Process exited after 0.3708 seconds with return value 0
请按任意键继续. . .

实例14.8

pairs.cpp

cpp 复制代码
// pairs.cpp -- defining and using a Pair template
#include<iostream>
#include<string>

template<class T1, class T2>
class Pair{
private:
    T1 a;
    T2 b;
public:
    T1 & first();
    T2 & second();
    T1 first() const { return a; }
    T2 second() const { return b; }
    Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) {}
    Pair() {}
};

template<class T1, class T2>
T1 & Pair<T1, T2>::first(){
    return a;
}

template<class T1, class T2>
T2 & Pair<T1, T2>::second(){
    return b;
}

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

    Pair<string, int> ratings[4] = {
        Pair<string, int>("The Purpled Duck", 5),
        Pair<string, int>("Jaquie's Frisco Al Rresco", 4),
        Pair<string, int>("Cafe Souffle", 5),
        Pair<string, int>("Bertie's Eats", 3)
    };

    int joints = sizeof(ratings) / sizeof(Pair<string, int>);
    cout << "Rating:\t Eatery\n";
    for (int i = 0; i < joints; i++){
        cout << ratings[i].second() << ":\t"
             << ratings[i].first() << endl;
    }
    cout << "Oops! Revised rating:\n";
    ratings[3].first() = "Bertie's Fab Eats";
    ratings[3].second() = 6;
    cout << ratings[3].second() << ":\t "
         << ratings[3].first() << endl;

    return 0;
}

编译运行结果:

cpp 复制代码
Rating:  Eatery
5:      The Purpled Duck
4:      Jaquie's Frisco Al Rresco
5:      Cafe Souffle
3:      Bertie's Eats
Oops! Revised rating:
6:       Bertie's Fab Eats

--------------------------------
Process exited after 0.3374 seconds with return value 0
请按任意键继续. . .

实例14.9

tempmemb.cpp

cpp 复制代码
// tempmemb.cpp -- template members

#include<iostream>

using std::cout;
using std::endl;

template<typename T>
class beta{
private:
    template <typename V> // nested template class member
    class hold{
    private:
        V val;
    public:
        hold(V v = 0) : val(v) {}
        void show() const { cout << val << endl; }
        V Value() const { return val; }
    };
    hold<T> q;      // template object
    hold<int> n;    // template object
public:
    beta( T t, int i) : q(t), n(i) {}
    template<typename U>    // template method
    U blab(U u, T t) { return (n.Value()+q.Value())*u / t;}
    void Show() const { q.show(); n.show(); }
};


int main(){
    beta<double> guy(3.5, 3);
    cout << "T was set to double\n";
    guy.Show();
    cout << "V was set to T, which is double, then V was set to int\n";

    cout << guy.blab(10, 2.3) << endl;
    cout << "U was set to int\n";

    cout << guy.blab(10.0, 2.3) << endl;
    cout << "U was set to double\n";

    cout << "Done\n";

    return 0;
}

编译运行结果:

cpp 复制代码
T was set to double
3.5
3
V was set to T, which is double, then V was set to int
28
U was set to int
28.2609
U was set to double
Done

--------------------------------
Process exited after 0.321 seconds with return value 0
请按任意键继续. . .

实例14.10

tempparm.cpp

cpp 复制代码
// tempparm.cpp - template as parameters
#include <iostream>
#include"stacktp.h"

template < template <typename T> class Thing>
class Crab{
private:
    Thing<int> s1;
    Thing<double> s2;
public:
    Crab() { };
    // assume the thing class push() and pop() members
    bool push(int a, double x) { return s1.push(a) && s2.push(x); }
    bool pop(int &a, double & x) { return s1.pop(a) && s2.pop(x); }
};

int main(){
    using std::cout;
    using std::cin;
    using std::endl;
    Crab<Stack> nebula; // Stack must match template <typename T> class thing
    int ni;
    double nb;
    cout << "Enter int double pairs, such as 4 3.5 (0 0 to end):\n";
    while (cin >> ni >> nb && ni > 0 && nb > 0){
        if (!nebula.push(ni,nb)){
            break;
        }
    }
    while (nebula.pop(ni,nb))
        cout << ni << ", " << nb << endl;
    cout << "Done.\n";

    return 0;

}
加载之前的stacktp.h文件
编译运行结果:

```cpp
Enter int double pairs, such as 4 3.5 (0 0 to end):
50 22.48
25 33.87
60 19.12
0 0
60, 19.12
25, 33.87
50, 22.48
Done.

--------------------------------
Process exited after 23.26 seconds with return value 0
请按任意键继续. . .

实例14.11

frnd2tmp.cpp

cpp 复制代码
// frnd2tmp.cpp -- template class with non-template friends

#include <ctime>
#include<iostream>
using std::cout;
using std::endl;

template<typename T>
class HasFriend{
private:
    T item;
    static int ct;
public:
    HasFriend(const T & i) : item(i) { ct++; }
    ~HasFriend() { ct--; }
    friend void counts();
    friend void report(HasFriend<T> &); // template parameter
};

// each specialization has its own static data member
template<typename T>
int HasFriend<T>::ct = 0;

// non-template friend to all HasFriend<T> classes
void counts(){
    cout << "int count: " << HasFriend<int>::ct << "; ";
    cout << "double count: " << HasFriend<double>::ct << endl;
}

// non-template friend to the HasFriend<int> class
void report(HasFriend<int> & hf){
    cout << "HasFriend<int>: " << hf.item << endl;
}

// non-template friend to the HasFriend<double class
void report(HasFriend<double> & hf){
    cout << "HasFriend<double>: " << hf.item << endl;
}

int main(){
    cout << "No objects declared: ";
    counts();
    HasFriend<int>hfil(10);
    cout <<"After hfil declared: ";
    counts();
    HasFriend<int>hfil2(20);
    cout << "After hfil2 declared: ";
    counts();
    HasFriend<double>hfdb(10.5);
    cout << "After hfdb declared: ";
    counts();
    report(hfil);
    report(hfil2);
    report(hfdb);

    return 0;

}
复制代码
编译运行结果:

```cpp
No objects declared: int count: 0; double count: 0
After hfil declared: int count: 1; double count: 0
After hfil2 declared: int count: 2; double count: 0
After hfdb declared: int count: 2; double count: 1
HasFriend<int>: 10
HasFriend<int>: 20
HasFriend<double>: 10.5

--------------------------------
Process exited after 0.3272 seconds with return value 0
请按任意键继续. . .

实例14.12

tmp2tmp.cpp

cpp 复制代码
// tmp2tmp.cpp -- template friends to a template class
#include<iostream>
using std::cout;
using std::endl;

// template prototypes
template<typename T> void counts();
template<typename T> void report(T &);

// template class
template <typename TT>
class HasFriendT{
private:
    TT item;
    static int ct;
public:
    HasFriendT(const TT & i) : item(i) { ct++; }
    ~HasFriendT() { ct--;}
    friend void counts<TT>();
    friend void report<>(HasFriendT<TT> &);
};

template<typename T>
int HasFriendT<T>::ct = 0;

// template friend functions definitions
template<typename T>
void counts(){
    cout << "template size: " << sizeof(HasFriendT<T>) << ": ";
    cout << "template counts(): " << HasFriendT<T>::ct << endl;
}

template<typename T>
void report(T & hf){
    cout << hf.item << endl;
}

int main(){
    counts<int>();
    HasFriendT<int> hfil(10);
    HasFriendT<int> hfil2(20);
    HasFriendT<double> hfdb(10.5);
    report(hfil); // generate report(HasFriendT<int> &)
    report(hfil2);  // generate report(HasFriendT<int> &)
    report(hfdb);   // generate report(HasFriendT<double> &)
    cout << "counts<int>() output: \n";
    counts<int>();
    cout << "counts<double>() output: \n";
    counts<double>();

    return 0;
}

编译运行结果:

cpp 复制代码
template size: 4: template counts(): 0
10
20
10.5
counts<int>() output:
template size: 4: template counts(): 2
counts<double>() output:
template size: 8: template counts(): 1

--------------------------------
Process exited after 0.3314 seconds with return value 0
请按任意键继续. . .

实例14.13

manyfrnd.cpp

cpp 复制代码
// manyfrnd.cpp -- unbound template friend to a template class
#include<iostream>

using std::cout;
using std::endl;

template<typename T>
class ManyFriend{
private:
    T item;
public:
    ManyFriend(const T & i) : item(i) { }
    template <typename C, typename D> friend void show2(C &, D &);
};

template <typename C, typename D> void show2(C & c, D & d){
    cout << c.item << ", " << d.item << endl;
}

int main(){
    
    ManyFriend<int> hfil(10);
    ManyFriend<int> hfil2(20);
    ManyFriend<double> hfdb(10.5);
    cout << "hfil, hfil2: ";
    show2(hfil, hfil2);
    cout << "hfdb, hfil2: ";
    show2(hfdb, hfil2);

    return 0;
}

编译运行结果:

cpp 复制代码
hfil, hfil2: 10, 20
hfdb, hfil2: 10.5, 20

--------------------------------
Process exited after 0.3257 seconds with return value 0
请按任意键继续. . .
相关推荐
im_AMBER12 分钟前
Leetcode 74 K 和数对的最大数目
数据结构·笔记·学习·算法·leetcode
DBA小马哥18 分钟前
Oracle迁移实战:如何轻松跨越异构数据库的学习与技术壁垒
数据库·学习·oracle·信创·国产化平替
断剑zou天涯34 分钟前
【算法笔记】蓄水池算法
笔记·算法
【上下求索】43 分钟前
学习笔记095——Ubuntu 安装 lrzsz 服务?
运维·笔记·学习·ubuntu
Benmao⁢1 小时前
C语言期末复习笔记
c语言·开发语言·笔记·leetcode·面试·蓝桥杯
咕咕嘎嘎10242 小时前
C++六个默认成员函数
c++
2401_834517072 小时前
AD学习笔记-27 泪滴的添加和移除
笔记·学习
zyq~2 小时前
【课堂笔记】凸优化问题-2
笔记
灰灰勇闯IT3 小时前
RN路由与状态管理:打造多页面应用
开发语言·学习·rn路由状态
亭上秋和景清3 小时前
指针进阶:函数指针详解
开发语言·c++·算法