0%

C++之类与对象

C++之类与对象……

C++中的类

1.组成

  • 类声明:以数据成员的方式描述数据部分,以成员函数(被称为方法)的方式描述公有接口
  • 类方法定义:描述如何实现类成员函数

2.公有与私有

  • 数据成员通常放在私有部分,组成类接口的成员函数放在共有部分
  • 使用类对象的程序都可以直接访问公有部分,但只能通过公有成员函数来访问对象的私有成员
  • 类声明中不加关键字默认为private

3.类的声明定义与类对象

  • stock00.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #ifndef __STOCK00__H__
    #define __STOCK00__H__

    #include<iostream>
    #include<string>

    using namespace std;

    //类的声明
    class Stock
    {
    private:
    string company;
    long shares;
    double share_val;
    double total_val;
    void set_tot(void){total_val=shares*share_val;}//其为内联函数,函数定义在类的声明中出现
    public:
    void acquire(const string &co,long n,double pr);
    void buy(long num,double price);
    void sell(long num,double price);
    void update(double price);
    void show();
    };

    #endif
  • stock00.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #include"stock00.h"

    //类的定义
    void Stock::acquire(const string &co,long n,double pr)
    {
    company=co;//类的成员函数可以直接访问私有数据成员
    if(n<0)
    {
    cout<<"Number of shares can not be negative!"<<endl;
    cout<<"So set "<<company<<" shares =0"<<endl;
    shares=0;
    }
    else
    {
    shares=n;
    }

    share_val=pr;

    set_tot();
    }

    void Stock::buy(long num,double price)
    {
    if(num<0)
    {
    cout<<"Number of shares you buy can not be negative!"<<endl;
    }
    else
    {
    shares+=num;
    share_val=price;
    set_tot();
    }
    }

    void Stock::sell(long num,double price)
    {
    if(num<0)
    {
    cout<<"Number of shares you sell can not be negative!"<<endl;
    }
    else if(num>shares)
    {
    cout<<"You can not sell more than you have!"<<endl;
    }
    {
    shares-=num;
    share_val=price;
    set_tot();
    }
    }

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

    void Stock::show()
    {
    cout<<"Company:"<<company<<endl;
    cout<<"Shares:"<<shares<<endl;
    cout<<"Share Price:"<<share_val<<endl;
    cout<<"Total Worth:"<<total_val<<endl;
    cout<<"---------------------------"<<endl;
    }
  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include<iostream>
    #include"stock00.h"

    using namespace std;

    int main(void)
    {
    //定义一个类的对象
    Stock sto;
    sto.acquire("NanoSmart",20,12.5);
    sto.show();

    sto.buy(15,17.125);
    sto.show();

    sto.sell(400,20);
    sto.show();

    sto.buy(3000,40.125);
    sto.show();

    sto.sell(1000,100);
    sto.show();

    return 0;
    }
  • 结果如下:

    image-20230207215318666

4.类的构造函数与析构函数

4.1 构造函数

  • 类构造函数就是用来初始化的

  • 构造函数的名称与类名一样,构造函数没有返回值

  • 用户自定义构造函数的调用:

    1
    2
    public:
    Stock(const string &co,long n,double pr);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Stock::Stock(const string &co,long n,double pr)
    {
    company=co;//类的成员函数可以直接访问私有数据成员
    if(n<0)
    {
    cout<<"Number of shares can not be negative!"<<endl;
    cout<<"So set "<<company<<" shares =0"<<endl;
    shares=0;
    }
    else
    {
    shares=n;
    }

    share_val=pr;

    set_tot();
    }
    • 显示调用:Stock garment = Stock("Furry", 50 ,2.5);
    • 隐式调用:Stock garment ("Furry", 50 ,2.5);
  • 默认构造函数的两种定义方式

    • 给构造函数的所有参数提供默认值

      1
      2
      3
      public:
      //默认构造函数定义方法1
      Stock(const string &co="Error",long n=0,double pr=0.0);
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      Stock::Stock(const string &co,long n,double pr)
      {
      company=co;//类的成员函数可以直接访问私有数据成员
      if(n<0)
      {
      cout<<"Number of shares can not be negative!"<<endl;
      cout<<"So set "<<company<<" shares =0"<<endl;
      shares=0;
      }
      else
      {
      shares=n;
      }

      share_val=pr;

      set_tot();
      }
    • 没有参数的构造函数

      1
      2
      3
      public:
      //默认构造函数定义方法2
      Stock();
      1
      2
      3
      4
      5
      6
      7
      Stock::Stock()
      {
      company="Error";
      shares=0;
      share_val=0;
      total_val=0;
      }
  • 默认构造函数的两种调用方式

    • 隐式调用:Stock garment;
    • 显示调用:stock garment=stock();

4.2 析构函数

  • 析构函数完成清理工作,例:如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存

  • 析构函数的名称是在类名前加上~,析构函数没有返回值和声明类型,例:~Stock()

  • 当对象被删除时,程序将调用析构函数,每个类只能由一个析构函数

  • stock00.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #ifndef __STOCK00__H__
    #define __STOCK00__H__

    #include<iostream>
    #include<string>

    using namespace std;

    //类的声明
    class Stock
    {
    private:
    string company;
    long shares;
    double share_val;
    double total_val;
    void set_tot(void){total_val=shares*share_val;}//其为内联函数,函数定义在类的声明中出现
    public:
    //默认构造函数定义方法1
    //Stock(const string &co="Error",long n=0,double pr=0.0);
    //默认构造函数定义方法2
    Stock();
    Stock(const string &co,long n,double pr);
    //析构函数
    ~Stock();
    void buy(long num,double price);
    void sell(long num,double price);
    void update(double price);
    void show();
    };

    #endif
  • stock00.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    #include"stock00.h"

    //类的定义
    Stock::Stock()
    {
    company="Error";
    shares=0;
    share_val=0;
    total_val=0;
    }
    Stock::Stock(const string &co,long n,double pr)
    {
    company=co;//类的成员函数可以直接访问私有数据成员
    if(n<0)
    {
    cout<<"Number of shares can not be negative!"<<endl;
    cout<<"So set "<<company<<" shares =0"<<endl;
    shares=0;
    }
    else
    {
    shares=n;
    }

    share_val=pr;

    set_tot();
    }

    Stock::~Stock()
    {
    cout<<"Bye "<<company<<endl;
    }

    void Stock::buy(long num,double price)
    {
    if(num<0)
    {
    cout<<"Number of shares you buy can not be negative!"<<endl;
    }
    else
    {
    shares+=num;
    share_val=price;
    set_tot();
    }
    }

    void Stock::sell(long num,double price)
    {
    if(num<=0)
    {
    cout<<"Number of shares you sell can not be negative!"<<endl;
    }
    else if(num>shares)
    {
    cout<<"You can not sell more than you have!"<<endl;
    }
    else
    {
    shares-=num;
    share_val=price;
    set_tot();
    }
    }

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

    void Stock::show()
    {
    cout<<"Company:"<<company<<endl;
    cout<<"Shares:"<<shares<<endl;
    cout<<"Share Price:"<<share_val<<endl;
    cout<<"Total Worth:"<<total_val<<endl;
    cout<<"---------------------------"<<endl;
    }
  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include<iostream>
    #include"stock00.h"

    using namespace std;

    int main(void)
    {
    Stock garment;
    garment.show();

    Stock sto("NanoSmart",20,12.5);
    sto.show();

    Stock sto2("Fultty",50,20.7);
    sto2.show();

    //类对象之间可以直接赋值
    sto=sto2;
    sto.show();
    sto2.show();
    }
  • 结果如下:

    image-20230208120000805

5.const成员函数

  • 在类方法后加上const,能保证类方法不修改调用对象
1
2
public:
void show() const;
1
2
3
4
5
6
7
8
void Stock::show() const
{
cout<<"Company:"<<company<<endl;
cout<<"Shares:"<<shares<<endl;
cout<<"Share Price:"<<share_val<<endl;
cout<<"Total Worth:"<<total_val<<endl;
cout<<"---------------------------"<<endl;
}
1
2
3
4
5
6
int main(void)
{
const Stock csto("Huawei",89,12.3);
csto.show();
return 0;
}

this指针

  • this指针指向调用成员函数的那个对象

  • this是对象的地址,*this才是对象本身

  • stock10.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #ifndef __STOCK10__H__
    #define __STOCK10__H__

    #include<iostream>
    #include<string>

    using namespace std;

    //类的声明
    class Stock
    {
    private:
    string company;
    long shares;
    double share_val;
    double total_val;
    void set_tot(void){total_val=shares*share_val;}//其为内联函数,函数定义在类的声明中出现
    public:
    //默认构造函数定义方法1
    //Stock(const string &co="Error",long n=0,double pr=0.0);
    //默认构造函数定义方法2
    Stock();
    Stock(const string &co,long n,double pr);
    //析构函数
    ~Stock();
    const Stock & topval(const Stock &s) const;
    void show() const;
    };

    #endif
  • stock10.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include"stock10.h"

    //类的定义
    Stock::Stock()
    {
    company="Error";
    shares=0;
    share_val=0;
    total_val=0;
    }
    Stock::Stock(const string &co,long n,double pr)
    {
    company=co;//类的成员函数可以直接访问私有数据成员
    if(n<0)
    {
    cout<<"Number of shares can not be negative!"<<endl;
    cout<<"So set "<<company<<" shares =0"<<endl;
    shares=0;
    }
    else
    {
    shares=n;
    }

    share_val=pr;

    set_tot();
    }

    Stock::~Stock()
    {
    cout<<"Bye "<<company<<endl;
    }

    const Stock & Stock::topval(const Stock &s) const
    {
    if(s.total_val>total_val) //这里的total_val代表this->total_val
    return s;
    else
    return *this;
    }

    void Stock::show() const
    {
    cout<<"Company:"<<company<<endl;
    cout<<"Shares:"<<shares<<endl;
    cout<<"Share Price:"<<share_val<<endl;
    cout<<"Total Worth:"<<total_val<<endl;
    cout<<"---------------------------"<<endl;
    }
  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include<iostream>
    #include"stock10.h"

    using namespace std;

    int main(void)
    {

    Stock sto("NanoSmart",20,12.5);
    sto.show();

    Stock csto("Huawei",89,12.3);
    csto.show();

    cout<<"The max is:"<<endl;
    Stock top=sto.topval(csto);
    top.show();
    return 0;
    }
  • 结果如下:

    image-20230208164703776


对象数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream>
#include"stock10.h"

using namespace std;

const int STKS=4;

int main(void)
{
//创建类对象:与创建数组一样
//并给对象赋初始值
Stock stocks[STKS]={
Stock("NanoSmart",12,20),
Stock("Boffo Object",200,2.0),
Stock("Mono",130,3.25)
};
//显示创建的类对象数据
for(int st=0;st<STKS;st++)
{
stocks[st].show();
}
//找出对象数组中价值最大的股票
const Stock *top=&stocks[0];
for(int st=1;st<STKS;st++)
{
top=&top->topval(stocks[st]);
}
top->show();

return 0;
}

结果如下:

image-20230208171159900


抽象数据类型

  • 利用类实现栈操作

  • stack.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #ifndef __STAKC_H__
    #define __STACK_H__

    typedef unsigned long Item;

    class Stack
    {
    private:
    //作用域为类的常量表示方法1:enum
    enum {MAX = 10};
    //作用域为类的常量表示方法2:利用static关键字
    //static const int MAX=10;
    Item items[MAX];
    int top;
    public:
    Stack();
    bool isempty() const;
    bool isfull() const;
    bool push(Item &item);
    bool pop(Item &item);
    };

    #endif
  • stack.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include "stack.h"

    Stack::Stack()
    {
    top = 0;
    }

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

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

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

    bool Stack::pop(Item &item)
    {
    if(top > 0)
    {
    item = items[--top];
    return true;
    }
    else
    return false;
    }
  • stacker.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <iostream>
    #include "stack.h"
    #include <cctype>

    using namespace std;

    int main(void)
    {
    char ch;
    unsigned long po;
    Stack st;

    cout << "Please etner A to push to stack, \n"
    << "P to pop from stack, Q to quit.\n";

    while(cin >> ch && toupper(ch) != 'Q')
    {
    while(cin.get() != '\n')
    continue;

    switch(ch)
    {
    case 'A':
    case 'a':
    cout << "Enter a number you want to push to stack:\n";
    cin >> po;
    cout<<"----------------------------------"<<endl;
    if(st.isfull())
    cout << "Stack already full" << endl;
    else
    st.push(po);
    break;
    case 'P':
    case 'p':
    if(st.isempty())
    cout << "Stack is empty" << endl;
    else
    {
    st.pop(po);
    cout << po << " is poped" << endl;
    cout<<"----------------------------------"<<endl;
    }
    break;
    }
    cout << "Please enter A to push to stack, \n"
    << "P to pop from stack, Q to quit.\n";
    }

    return 0;
    }
  • 结果如下:

    image-20230208182407710


实例:类实现简单列表

  • list.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #ifndef __LIST_H__
    #define __LIST_H__

    #include <iostream>

    typedef unsigned long Item;

    using namespace std;

    void visit_item(Item &item);

    class List
    {
    private:
    enum {MAX = 10};
    Item items[MAX];
    int top;
    public:
    List();
    bool isempty() const;
    bool isfull() const;
    bool add(Item &item);
    void visit(void (*pf)(Item &));
    };

    #endif
  • list.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include "list.h"

    List::List()
    {
    top = 0;
    }

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

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

    bool List::add(Item &item)
    {
    if(top < MAX)
    {
    items[top++] = item;
    return true;
    }
    else
    return false;
    }

    void List::visit(void (*pf)(Item &))
    {
    for(int i = 0; i < top; i++)
    pf(items[i]);
    }

    void visit_item(Item &item)
    {
    cout << "Item = " << item << endl;
    }
  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <iostream>
    #include "list.h"

    using namespace std;

    int main(void)
    {
    List list;
    Item num;

    for(int i = 0; i < 5; i++)
    {
    cout << "Please enter a number: ";
    cin >> num;
    list.add(num);
    }

    list.visit(visit_item);

    return 0;
    }
  • 结果如下:

    image-20230208203815674

欢迎来到ssy的世界