这部分是c++升级c的主要内容,也是c++的精髓部分,c是面向过程的,而C++是面向对象的。面向对象编程(OOP)的最重要特性有:
*抽象
*封装和数据隐藏
*多态
*继承
*代码的可重用性
1.抽象和类:
C++中的类,是一种将抽象将抽象转换为用户定义类型的C++工具(其他面向对象语言也类似,如java),它将数据表示和操纵数据的方法组合成一个整
洁的包。
定义类的规范有两个部分:类声明和类方法定义。
类声明:以数据成员的方式描述数据部分,以成员函数(也成为方法)的方式描述公有接口。
类方法定义:描述如何实现类成员函数。
简单地说就是,类声明提供了类的蓝图,而类的方法定义则提供了实现细节。
对类成员的控制访问:由于隐藏数据时oop的主要目标之一,所以数据项通常放在私有部分(private),组成类接口的成员函数放在公有部分,否则就无
法从程序中调用这些函数,一般使用私有成员函数来处理不属于公共接口的实现细节。有时候不必使用private关键字,因为C++中,private是类对象默认
访问控制。
现在学了类了,对类和结构的区别有了更进一步的了解:实际上类是对结构的扩展,他们有很多的相同特性,唯一区别是,结构的默认访问控制室public,
类是private的。注意:结构体也可以定义方法:例如如下:
public struct Person
{
string name;
double height;
double weight;
public void OverWeight()
{
.....
}
}
成员函数的定义:与常规函数定义非常相似,但是有两个特色的特征:
(1)定义成员函数是,使用作用域解析操作符(::)来标识函数所属的类
(2)类方法可以访问类的private组件
代码示例:
#include
#include
using namespace std;
//类声明
class Stock
{
private:
char company[30];//公司名称
int shares;//所持股票的数量
double share_val;//每股的价格
double total_val;//股票总值
void SetTol()//这是个内陆函数
{
total_val=shares*share_val;
}
public:
void Acquire(const char *co,int n,double pr);//获得股票
void Buy(int num,double price);//增持股票
void Sell(int num,double price);//卖出股票
void Update(double price);//更新股票价格
void Show();//显示关于所持股票的信息
};
//定义类的成员函数
void Stock::Acquire(const char *co,int n,double pr)
{
strncpy(company,co,29);
company[29]='\0';
if(n<0)
{
cerr <<"股票数量不能为负的!"< cerr < shares = 0; } else shares = n; share_val = pr; SetTol(); } void Stock::Buy(int num,double price) { if(num<0) { cerr<<"增持股票数量不能为负的!"< } else { shares +=num; share_val=price; SetTol(); } } void Stock::Sell(int num,price) { if(num<0) { cerr<<"卖出股票数量不能为负的!"< } if(num>shares) { cerr<<"你卖出的股票数量不能大于你所持有的数量"< } else { shares = shares - num; share_val=price; SetTol(); } } void Stock::Update(double price) { share_val=price; SetTol(); } void Stock::Show() { cout <<"company: "< cout <<" shares: "< cout <<"share price:$"< cout <<"total Worth:$"< } cerr对象:和cout对象一样,也是一个ostream对象,之间的区别在于,操作系统重定向只影响cout,而不影响cerr。cerr对象用于错误信息 内联方法:在类声明中定义的的函数都将自动成为内联函数。因此以上SetTol()函数就是内联函数 注意:调用成员函数时,它将使用被用来调用它的对象的成员数据。所创建的对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个累的 所有对象共享同一组类方法,集每个方法(函数)只有一个副本。 2.类的构造函数和析构函数: 构造函数:是创建对象是自动调用的,但是不能通过对象来调用构造函数。还有就是不能将类成员名称用作构造函数的参数! 析构函数:用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止。对象过期时,程序将自动调用一个特殊的函数来完成清理工作,这个函数就是析构函数 代码示例: stock.h文件代码: #include #include using namespace std; //类声明 class Stock { private: char company[30];//公司名称 int shares;//所持股票的数量 double share_val;//每股的价格 double total_val;//股票总值 void SetTol()//这是个内陆函数 { total_val=shares*share_val; } public: Stock(); Stock(const char *co,int n,double pr); ~Stock(); void Acquire(const char *co,int n,double pr);//获得股票 void Buy(int num,double price);//增持股票 void Sell(int num,double price);//卖出股票 void Update(double price);//更新股票价格 void Show();//显示关于所持股票的信息 }; stock.cpp文件代码: #include #include #include"stock.h" using namespace std; //类的实现 //定义类的成员函数 Stock::Stock()//默认构造函数 { cout<<"Default constructor called:"< strcpy(company,"noname"); shares=0; share_val=0.0; total_val=0.0; } Stock::Stock(const char *co ,int n,double pr)//构造函数 { cout<<"Constructor using:"< strncpy(company,co,29); company[29]='\0'; if(n<0) { cerr <<"股票数量不能为负的!"< cerr < shares = 0; } else shares = n; share_val = pr; SetTol(); } Stock::~Stock()//析构函数 { cout<<"bye, "< } void Stock::Buy(int num,double price) { if(num<0) { cerr<<"增持股票数量不能为负的!"< } else { shares +=num; share_val=price; SetTol(); } } void Stock::Show() { cout <<"company: "< cout <<" shares: "< cout <<"share price:$"< cout <<" total Worth:$"< cout < } main.cpp文件代码: #include #include #include #include"stock.h" using namespace std; int main(int argc, char *argv[]) { cout.setf(ios_base::fixed);//格式化 cout.precision(2);//格式化 cout.setf(ios_base::showpoint);//格式化 cout<<"Using constructor to new objects:"< Stock stock1("NanoSmart",12,20.0); stock1.Show(); Stock stock2=Stock("Boffo Objects",2,2.0); stock2.Show(); cout<<"Assigning stock1 to stock2:"< stock2=stock1; cout<<"Listing stock1 and stock2:"< stock1.Show(); stock2.Show(); cout<<"Using a constructor to reset an object:"< stock1=Stock("Nifty Food",10,50.0); cout<<"Revised stock1:"< stock1.Show(); cout<<"Done\n"; return 0; } 以上三个文件编译连接运行后的结果如下: 想想结果为什么会这样?? const 成员函数:将const放在类函数之后,如 void Show()const,这样定义就是const成员函数,一般情况下,只要类方法不修改对象,则就应该将其声明为const。 构造函数的特例:接受一个参数的构造函数允许使用赋值句法来将对象初始化一个值,如构造函数原型为:Bob(int age); 则可以这样初始化:Bob czm=22;这是第三种初始化对象的方法。 3.this指针:指向用来调用成员函数的对象(this被作为隐藏参数传递给方法)。每个成员函数(包括构造函数和析构函数)都有一个this指针,this指针指向调用对象,this也是一个指针,所以和一般的指针一样,*this指针指向的值。 代码示例: const Stock& Stock::Topval(const Stock & s) const { if (s.total_val>total_val) return s; else return *this; } 4.对象数组:要创建类对象数组,这个类必须有默认构造函数。因为初始化对象数组时,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时变量,然后将临时变量的内容复制到相应的元素中。如:Stock stk[4] = {Stock("caizhiming",2,20),Stock("caizhicong"),Stock("caizhiming2",333,34),}; 现在对this指针比较了解了,现在深入了解C++的工作方式,比如C++前端cfront将c++程序转换为c程序:处理方法的定义时,只需将下面C++的定义: void Stock::Show()const { cout <<"company: "< cout <<" shares: "< cout <<"share price:$"< cout <<" total Worth:$"< } 转换为类C风格的定义: void Show(const Stock *this) { cout <<"company: "< cout <<" shares: "< cout <<"share price:$"< cout <<" total Worth:$"< } 同样的,将top.Show()转换为Show(&top) 5.小结: 面向对象编程强调的是程序如何表示数据。类是用户定义的类型,而对象则是类的实例,即对象是这种类型的变量。如果希望成员函数对多个对象进行操作,则可以将额外的对象作为参数传递给它。如果方法需要显示的引用调用它的对象,则可以使用this指针。