OOP特性:抽象,封装和数据隐藏,多态,继承,代码的可重用性
函数重载(函数多态):设计一系列的函数完成相同的工作或者说可以使用多个同名的函数
函数重载的关键是:参数列表(函数特征标)
类:
class Stock
{
private:
char company[30];
int shares;
double share_val;
double total_val;
void set_tot()
{
total_val = shares*share_val;
}
public:
void update(double price);
void show();
void buy(int num, double price);
};
一般来说,类有两部分组成:
1.类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口
2.类方法定义:描述如何实现类成员函数
关键字:Private:数据隐藏,是能通过Public内的成员函数访问Private里的成员。
Public:公开的
实现类成员函数:(两个特殊的特征)
1.定义成员函数时,使用作用域解析运算符(::)来标识函数所属的类
2.类方法可以访问类的Private组件
例如:
void Stock::Update(double price)
构造函数:
名称与类名相同,虽然没有返回值,但也没有被声明void类型(构造函数没有声明类型)
构造函数的参数名与成员名不要相同,否则会发生混乱。在程序声明对象时,会自动调用构造函数
每次创建对象时(甚至使用new分配内存时,C++都使用类构造函数),构造函数与new一起使用的方法:
Stock *postock = new Stock("XX", ,);
显式使用构造:
Stock food = Stock("XX", ,);
隐式使用构造:
Stock food(“XX”, ,);
一般来说:使用对象来调用方法,但无法调用构造函数,因为构造函数时构造对象的
默认构造函数:未提供显式初始值时,用来创建对象的构造函数。
默认构造函数没有任何参数,如果有,则必须给所有参数提供默认值。
在创建对象时,如果没有提供任何构造函数,则C++将会自动提供默认构造函数。
可能为:
Stock::Stock(){}
定义默认构造函数的两种方式:
1.给已有的构造函数的所有参数提供默认值
2.重载构造
Stock::Stock()
{
company = "no name";
shares = 0;
share_val = 0;
total_val = 0;
}
析构函数
析构函数:当对象过期时,程序会自动调用一个成员函数——析构函数(完成清理工作)
析构名称:在类型名字前加~ 析构函数没有返回值和声明类型,本身也不承担任何重要的功能
原型: ~Stock()
使用:
Stock::~Stock()
{
}
什么时候使用析构呢? 由编译器决定,通常不应在代码中显示调用
如果创建静态存储类对象:则其析构函数在程序结束后会自动调用
如果创建动态存储类对象:则其析构函数会在程序执行完代码块时自动被调用
如果对象通过new定义的,则它驻留在栈内存或自由存储区中,当使用delete释放内存时,析构自动被调用
注:
Stock Stock2 = Stock("xx", , );
Stock1 = Stock("xx", , );
这两条语句有根本性区别:
第一条语句是初始化,它创建有指定值的对象,可能会创建临时对象,也可能不会创建。
第二条语句是赋值,在赋值之前一定会调用构造创建一个临时对象,结束后调用析构。
如果可以既通过初始化,也可以通过赋值来设置对象的值,则应采用初始化方式(通常效率更高)。
C++11列表初始化,只要提供与某个构造函数的参数列表匹配的内容,并用大括号括起:
Stock jock = {"xx", , };
Const成员函数
const Stock land = Stock("xx", , );
land.show();
编译器将拒绝第二行,因为show()代码无法保证调用对象不被修改。
以前通过将函数参数声明为const引用或指向const的指针来解决这种问题,但是show()方法没有参数,这时需要一种特殊的语法。将const关键字放在函数的括号后面:
void show() const;
同样,函数定义的开头应该为:
void Stock :: show() const;