C++学习笔记4:对象和类

最近有点烦有点烦,还是学习使我快乐,嗯,学习使我快乐~

1. 过程性编程和面向对象编程

过程性编程:首先考虑要遵循的步骤,然后考虑如何表示这些数据。

面向对象编程:首先考虑数据(如何表示数据和如何使用数据),然后使用新的设计方案创建出程序。

2. 抽象和类

2.1 类规范

  • 类声明:以数据成员的方式描述数据部分,以成员函数(方法)的方式描述公有接口。放在头文件中
  • 类方法定义:描述如何实现类成员函数。放在源代码文件中
2.2 访问控制

  • public:使用类对象的程序可以直接访问公有成员
  • private:默认类型,只能通过公有成员函数(或者友元函数)访问对象的私有成员
  • protected
2.3 类和结构

结构具有与类相同的特性,它们唯一的区别是结构的默认访问类型是public,类的默认访问类型是private。但通常使用类实现类描述,结构只用来表示纯粹的数据对象。

2.4 实现类成员函数

  • 定义成员函数时,使用作用域解析运算符(::)来标识函数所属的类
  • 类方法可以访问类的private组件
#include 
   
   
    
    
#include "stock.h"
void Stock::acquire()
{
...
}
   
   
2.5 内联方法

  • 其定义位于类声明中的函数都将自动成为内联函数
  • 也可在类声明之外定义成员函数,使用inline限定符,使其成为内联函数。放在头文件中。
//stock.h
class Stock{
private:
  ...
  double total_val;
  void set_slot(){total_val = 0;}
public:
  void update(double val);
  ...
};
inline Stock::updte(double val)
{
  total_val = val;
}

2.6 方法使用哪个对象

使用成员运算符。

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

Stock kate,joe;
kate.show();
joe.show();

3. 类的构造函数和析构函数

3.1 声明和定义构造函数

  • 构造函数没有返回类型,位于类声明的共有部分,名称与类名称相同
  • 程序声明对象时,将自动调用构造函数
  • 一般在类成员变量的名称前加m_或者在后面加_后缀,以与构造函数的参数区分
3.2 使用构造函数

  • 分为显式调用和隐式调用,用new动态分配内存时也调用构造函数。
  • 构造函数被用来创建对象,而不能通过对象调用。
Stock food = Stock("World",250,1.2);
Stock garment("Furry",200,2.1);
Stock * pstock = new Stock("Amy",450,2.2);
3.3 默认构造函数

  • 当且仅当没有定义任何构造函数时,编辑器才会提供默认构造函数。
  • 为类定义了构造函数后,程序员就必须为类提供默认构造函数。
创建默认构造函数:

  • 给已有构造函数的所有参数提供默认值
  • 定义一个没有参数的构造函数
Stock(const String & co = "error",int n = 0,double pr = 0.0);
Stock();
使用默认构造函数:
Stock first;
Stock second = Stock();
Stock *prelist = new Stock;
3.4 析构函数
  • 对象过期时,编译器自动调用析构函数,不需要显示调用析构函数。
  • 如果程序员没有提供析构函数,则编译器隐式地声明一个默认的析构函数。
  • 析构函数为类名前加~,没有参数,可以没有返回值和声明类型。
  • 如果构造函数使用了new,则必须提供使用delete的析构函数。
3.5 初始化和赋值
如果既可以通过初始化,也可以通过赋值来设置对象的值,则应采用初始化的方式,通常这种方式效率更高。因为赋值的方式会先创建临时变量,再将临时变量的值赋给变量,最后删除临时变量。
Stock stock1 = Stock("Buff",2,2.0);
Stock stock2;
stock2 = Stock("Nifty",3,3.0);
3.6 对象列表初始化
列表初始化是C++11的特性,也可用于对象初始化。
Stock hot_tip = {"Ded",4,4.0};

3.7 const成员函数

  • 不会修改调用对象的成员函数为const成员函数
  • 只要类方法不修改调用对象,都应将其声明为const。
class Stock{
...
public:
  void show() const;
}
void Stock::show() const{
...
}

4. this指针

每个成员函数(包括构造函数和析构函数)都有一个this指针,this指针指向调用对象。

const Stock & Stock::toptal::(const Stock & s) const{
  if(s.total_val > total_val)
    return s;
  else
    return *this;
}

5. 类作用域

类中定义的名称的作用域为整个类,在类声明或成员函数定义时可以使用未修饰的成员名称(未限定的名称),其它情况使用类成员名称时,要使用直接成员运算符(.)、间接成员运算符(->)或者作用域解析符(::)。

5.1 作用域为类的常量

有两种方法可以实现作用域为类的常量:

  • 在类中声明一个没有变量名的枚举,用枚举为整形常量提供作用域为整个类的符号名称。用这种方法创建的枚举并不会创建类数据成员,也就是说所有对象都不包含枚举。另外,下例中的 Moths只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用30替换它。
class Bakery{
private:
  enum {Moths = 30};
  double costs[Moths];
  ...
}
  • 使用关键字static,该变量与其它静态变量存储在一起,而不是存储在对象中。因此只有一个该常量,被所有对象共享。
static const int Moths = 30;
5.2 作用域内枚举(C++11)

  • 传统枚举的问题:两个枚举定义中的枚举量可能发生冲突
enum egg {Small, Medium, Large, Jumbo};
enum t_shirt {Small, Medium, Large, Xlarge};
  • C++11提供的作用域为类的枚举量避免了这种冲突,使用关键字class或者struct。要使用枚举名限定枚举量。
enum class egg {Small,Medium,Large,Jumbo};
enum class t_shirt {Small,Medium,Large,Xlarge};
egg choice = egg::Large;
t_shirt Floyd = t_shirt::Large;
  • 在有些情况下,常规枚举将自动转化为整形,如将其赋给int变量或者用于比较表达式时,但作用域内枚举不能隐式地转换为整形,但可进行显示类型转换。
enum egg {Small,Medium,Large};
enum class t_shirt {Small,Medium,Large,Xlarge};
egg one = Medium;
t_shirt rolf = t_shirt::Large;
int king = one;    //allowed
int ring = rolf;  // not allowed
if(king < Large)   //allowed
  cout <
   
   
  • 枚举用某种底层整形类型表示,在C++98中,如何选择取决于实现。在C++11中,作用域内枚举的底层类型默认为int,而且可以由程序代码指定;常规枚举的底层类型随实现而异,也可以指定。
enum class : short pizza {Small,Medium,Large};

6. 抽象数据类型

类概念非常适合与抽象数据类型。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值