C++学习随笔之七:对象和类

这部分是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<iostream>

#include<cstring>

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 <<"股票数量不能为负的!"<<endl;

    cerr <<company<<"的股票数量设置为0"<<endl;

    shares = 0; 

}

else

    shares = n;

share_val = pr;

SetTol();

void Stock::Buy(int num,double price)

{

if(num<0)

{

    cerr<<"增持股票数量不能为负的!"<<endl;

}

else

{

    shares +=num;

    share_val=price;

    SetTol();

}

void Stock::Sell(int num,price)

{

if(num<0)

{

    cerr<<"卖出股票数量不能为负的!"<<endl;

}

if(num>shares)

{

    cerr<<"你卖出的股票数量不能大于你所持有的数量"<<endl;

}

else

{

    shares = shares - num;

    share_val=price;

    SetTol();

}

}

void Stock::Update(double price)

{

share_val=price;

SetTol();

void Stock::Show()

{

cout <<"company: "<<company;

cout <<"  shares: "<<shares<<endl;

cout <<"share price:$"<<share_val;

cout <<"total Worth:$"<<total_val<<endl;

}

   cerr对象:和cout对象一样,也是一个ostream对象,之间的区别在于,操作系统重定向只影响cout,而不影响cerr。cerr对象用于错误信息

内联方法:在类声明中定义的的函数都将自动成为内联函数。因此以上SetTol()函数就是内联函数

注意:调用成员函数时,它将使用被用来调用它的对象的成员数据。所创建的对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个累的 所有对象共享同一组类方法,集每个方法(函数)只有一个副本。

2.类的构造函数和析构函数:

构造函数:是创建对象是自动调用的,但是不能通过对象来调用构造函数。还有就是不能将类成员名称用作构造函数的参数!

析构函数:用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止。对象过期时,程序将自动调用一个特殊的函数来完成清理工作,这个函数就是析构函数

代码示例:

stock.h文件代码:

#include<iostream>

#include<cstring>

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<iostream>

#include<cstring>

#include"stock.h"

using namespace std;

//类的实现 

//定义类的成员函数

Stock::Stock()//默认构造函数 

{

cout<<"Default constructor called:"<<endl;

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:"<<endl;

strncpy(company,co,29);

company[29]='\0';

if(n<0)

{

    cerr <<"股票数量不能为负的!"<<endl;

    cerr <<company<<"的股票数量设置为0"<<endl;

    shares = 0; 

}

else

    shares = n;

share_val = pr;

SetTol();

}

Stock::~Stock()//析构函数

{

cout<<"bye, "<<company<<"!"<<endl;//输出只是为了了解什么时候析构函数被调用。

}

void Stock::Buy(int num,double price)

{

if(num<0)

{

    cerr<<"增持股票数量不能为负的!"<<endl;

}

else

{

    shares +=num;

    share_val=price;

    SetTol();

}

void Stock::Show()

{

cout <<"company: "<<company;

cout <<"  shares: "<<shares<<endl;

cout <<"share price:$"<<share_val;

cout <<"  total Worth:$"<<total_val<<endl;

cout <<endl; 

}

main.cpp文件代码:

#include <cstdlib>

#include <iostream>

#include<cstring>

#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:"<<endl;

Stock stock1("NanoSmart",12,20.0);

stock1.Show();

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

stock2.Show();

cout<<"Assigning stock1 to stock2:"<<endl;

stock2=stock1;

cout<<"Listing stock1 and stock2:"<<endl;

stock1.Show();

stock2.Show();

cout<<"Using a constructor to reset an object:"<<endl;

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

cout<<"Revised stock1:"<<endl;

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: "<<company;

cout <<"  shares: "<<shares<<endl;

cout <<"share price:$"<<share_val;

cout <<"  total Worth:$"<<total_val<<endl;

}

转换为类C风格的定义:

void Show(const Stock *this)

{

cout <<"company: "<<this->company;

cout <<"  shares: "<<this->shares<<"\n";

cout <<"share price:$"<<this->share_val;

cout <<"  total Worth:$"<<this->total_val<<"\n";

}

同样的,将top.Show()转换为Show(&top)

5.小结:

面向对象编程强调的是程序如何表示数据。类是用户定义的类型,而对象则是类的实例,即对象是这种类型的变量。如果希望成员函数对多个对象进行操作,则可以将额外的对象作为参数传递给它。如果方法需要显示的引用调用它的对象,则可以使用this指针。

原文地址:https://www.cnblogs.com/JczmDeveloper/p/2964810.html