C++ Primer Plus 第十章 对象和类

对象和类

抽象和类

类是一种将抽象转换为用户定义类型的C++工具,他讲数据表示和操纵数据的方法组合成一个整洁的包

类规范:

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

控制访问:

关键字 private 和 pubilc 和 protected.

只能通过公有成员函数(或友元函数)来访问对象的私有成员。将实现希捷放在一起并将他们与抽象分开被称为封装。数据隐藏是一个种封装。封装的另一个例子是,将函数定义和类声明放在不同的文件中。

  • private:
    有该关键字的成员只能通过公共成员访问(数据隐藏)
  • public:
    该表示组成类的公共接口的类成员(抽象)
  • 成员可以是数据也可以是函数。

不必在类声明中使用关键字private,因为这是类对象的默认访问控制。

  • 定义成员函数时,使用作用域解析运算符(::)来表示函数所属的类。
  • 类方法可以访问类的private组件。

内联方法:

其定义位于类声明中的函数都将自动称为内联函数。如果愿意,也可以在类声明之外定义成员函数,并使其成为内联函数。为此,只需要在类实现部分中定义函数时加上inline限定符即可。

在类声明中定义方法和上述方式定义方法(使用inline)是等价的。

使用对象:

class Stock{
    ...
};
Stock kate,joe;
kate.show();

在kate.show()函数中,使用的类成员shares会被解释称kate.shares.

所创建的每个新对象都有自己的存储空间,用于存储器内部变量和类成员。但同一个类的所有对象共享同一组方法,即每种方法只有一个副本。

使用类

创建类:声明类变量,使用new为类对象分配存储空间。

类的构造函数和析构函数

类可以像结构一个初始化,前提是数据是public的

声明和定义构造函数:

构造函数的名称和类名相同,构造函数的原形和函数头没有返回值。(构造函数没有声明类型)

如果在类定义中有如下原形:

class Stock{
public:
    Stock(const string & co, long n = 0, double pr = 0.0); //参数名不能与类成员相同。
    ...
}

为了避免参数名混乱,可以在类参数前面使用m_的前缀,或者在最后使用_的后缀。(可以把构造函数定义为private)

使用构造函数:

C++有两种使用构造函数来初始化对象的方式,第一种方式是显式地调用构造函数:

```c++
Stock food = Stock("World Cabage", 250, 1.25);

另一种方式是隐式地调用构造函数:

Stock garment("Furry Mason", 50, 2.5);

这两种构造方式是等价的。

下面是使用new创建类对象:

Stock *pstock = new Stock("Electroshock Games", 18, 19.0);

无法使用对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的,因此构造函数被用来创建对象,而不能通过对象来调用。

默认构造函数:

默认构造函数是在未踢狗显示初始值时,即:

Stock fluffy_the_cat;

如果没有提供任何构造函数,则C++将自动提供默认的构造函数。如果提供了非默认构造函数,但是没有提供默认构造函数,则直接声明会出错。

可以通过函数重载来定义另一个构造函数————一个没有任何参数的构造函数或给所有的参数都提供默认值:

Stock();
//or:
Stock(const string & co = "Error", int n = 0, double pr = 0.0);

隐式地调用默认构造函数时,不要使用圆括号:

Stock second();

这是一个函数声明,不是对象调用构造函数。

析构函数

对象过期时,程序将自动调用一个特殊的成员函数————析构函数。

析构函数的名称很特殊:在类名前加上~。
因此Stock类的析构函数是~Stock()。

析构函数没有参数,因此Stock析构函数的原形必须是这样的:

~Stock();

析构函数可以如下定义:

Stock::~Stock(){
    cout << "Bye," << endl;
}
  • 析构函数的调用由编译器决定,通常不应在代码中显示调用析构函数。
  • 如果是静态存储对象,则析构函数将在程序结束时自动被调用。
  • 如果创建的是自动存储类对象,则析构函数将在程序执行完代码块时自动被调用。
  • 如果对象是通过new创建的,当使用delete来释放内存的时候,其析构函数将自动被调用。

对于

Stock stock2 = Stock("Boffo Objects",2,2.0);

在c++标准中,允许编译器使用两种方式来执行。一种是和 stock2(“Boffo Objects”,2,2.0)一样的语法,另一种是先创建一个临时对象,然后将该临时对象复制到stock2中,并丢弃它。如果此时使用析构函数,那么在丢弃时会调用。

C++中允许:

stock1 = Stock("Nifty Foods", 10, 50.0);

创建一个新的临时对象,然后复制到已有的对象中,再把该临时对象删除。

上述两个代码块中的语句有根本性的区别。

在C++中,可将列表初始化语法用于类。只要提供与某个构造函数的参数列表匹配的内容,并用大括号将它们括起来。

例如:

Stock hot_tip = {"Derivatives Plus Plus", 100, 45.0};
Stock temp {};

const 成员对象:

使用const定义的对象,不能调用非const的成员函数,否则程序报错。

const成员函数定义方法:const关键字放在函数的括号后面。例如:

//在声明中:
void show() const;
...
//在定义中:
void stock::show() const{
    ...
}

如果构造函数只接受一个参数,则可以像int char变量赋值一样初始化

this指针

对象可以访问同类对象的私有成员

在一个对象中,this表示指向该对象的一个指针。在成员函数中调用成员时,都是this的缩写。例如:

a;
this->a;

对象数组

emmm

类作用域

在类中定义的名称的作用域都为整个类,类作用域以为着不能从外部直接访问类成员,公有成员函数也是如此。

要调用公有成员函数,必须通过对象。

在类声明或成员函数定义中,额昆虫直接使用未修饰的成员名称。其他情况下,必须使用直接成员运算符、间接成员运算符或作用域解析运算符。(. -> :😃

作用域为类的常量:

  1. 枚举

    class Bakery{
    private:
        enum {Months = 12};
        double costs[Months];
        ...        
    };
    

    使用这种方式的声明枚举并不会创建数据成员。也就是所有的对象中不包含枚举。

  2. 关键字static:

    class Bakery{
    private:
        static const int Months = 12;
        double costs[Months];    
    };
    

    该变量将于其他静态变量存储在一起,而不是存储在对象中。

抽象数据类型

pass

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值