当前位置:编程学习 > C/C++ >>

c++面向对象的编程入门篇-----类(class)

上两篇内容我们着重说了结构体相关知识的操作。

以后的内容我们将逐步完全以c++作为主体了,这也以为着我们的教程正式进入面向对象的编程了。

前面的教程我已经再三说明,结构体的掌握非常重要,重要在哪里呢?重要在结构体和类有相同的特性,但又有很大的区别,类是构成面向对象编程的基础,但它是和结构体有着机器密切的关系。

我们在c语言中创建一个结构体我们使用如下方法:


//程序作者:管宁
//站点:www.易做图ev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

struct test
{
private:
int number;
public:
float socre;
};


类的创建方式和结构体几乎一样看如下的代码:


//程序作者:管宁
//站点:www.易做图ev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

class test
{
private:
int number;
public:
float socre;
public:
int rp()
{
return number;
}
void setnum(int a)
{
number=a;
}
};



但是大家注意到没有,标准c中是不允许在结构体中声明函数的,但c++中的类可以,这一点就和c有了本质的区别,很好的体现了c++面向对象的特点!

过去的c语言是一种非面向对象的语言

他的特性是

程序=算法+数据结构

但c++的特性是

对象=算法+数据结构
程序=对象+对象+对象+对象+........

所以根据这一特性,我们在定义一个自己定义的结构体变量的时候,这个变量就应该是叫做对象或者叫实例

例如

test a;
那么a就是test结构的一个对象(实例)

test结构体内的成员可以叫做是分量,例如:

a.socre=10.1f;
那么number就是test结构的对象a的分量(或者叫数据成员,或者叫属性)score;

在c语言中结构体中的各成员他们的默认存储控制是public 而 c++中类的默认存储控制是private,所以在类中的成员如果需要外部掉用一定要加上关键字public声明成公有类型,这一特性同样使用于类中的成员函数,函数的操作方式和普通函数差别并不大

例如上面的例子中的rp()成员函数,我们如故有如下定义

test a;
的话,调用rp()就应该写成

a.rp();

成员函数的调用和普通成员变量的调用方式一致都采用.的操作符。

这一小节为了巩固联系我给出一个完整的例子。

如下(重要和特殊的地方都有详细的注解):


//程序作者:管宁
//站点:www.易做图ev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

#include <iostream>
using namespace std;
class test
{
private://私有成员类外不能够直接访问
int number;
public://共有成员类外能够直接访问
float socre;
public:
int rp()
{
return number;
}
void setnum(int a)
{
number=a;
}
};

void main()
{
test a;
//a.number=10;//错误的,私有成员不能外部访问
a.socre=99.9f;
cout<<a.socre<<endl;//公有成员可以外部访问
a.setnum(100);//通过公有成员函数setnum()间接对私有成员number进行赋值操作
cout<<a.rp();//间接返回私有成员number的值
cin.get();
}

 

好了,介绍了在类内部定义成员函数(方法)的方法,下面我们要介绍一下域区分符(::)的作用了。

下面我们来看一个例子,利用这个例子中我们要说明两个重要问题:


//程序作者:管宁
//站点:www.易做图ev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

#include <iostream>
using namespace std;
int pp=0;
class test
{
private:
int number;
public:
float socre;
int pp;
public:
void rp();
};
void test::rp()//在外部利用域区分符定义test类的成员函数
{
::pp=11;//变量名前加域区分符给全局变量pp赋值
pp=100;//设置结构体变量
}

void main()
{
test a;
test b;
a.rp();
cout<<pp<<endl;
cout<<a.pp<<endl;

cin.get();
}

问题1:


利用域区分符我们可以在类定义的外部设置成员函数,但要注意的是,在类的内部必须预先声明:

void test::rp()

在函数类型的后面加上类的名称再加上域区分符(::)再加函数名称,利用这样的方法我们就在类的外部建立了一个名为rp的test类大成员函数(方法),可能很多人要问,这么做有意义吗?在类的内部写函数代码不是更好?
答案是这样的:在类的定义中,一般成员函数的规模一般都比较小,而且一些特殊的语句是不能够使用的,而且一般会被自动的设置成为inline(内联)函数,即使你没有明确的声明为inline,那么为什么有会被自动设置成为inline呢?因为大多数情况下,类的定义一般是放在头文件中的,在编译的时候这些函数的定义也随之进入头文件,这样就会导致被多次编译,如果是inline的情况,函数定义在调用处扩展,就避免了重复编译的问题,而且把大量的成员函数都放在类中使用起来也十分不方便,为了避免这种情况的发生,所以c++是允许在外部定义类的成员函数(方法)的,将类定义和其它成员函数定义分开,是面向对象编程的通常做法,我们把类的定义在这里也就是头文件了看作是类的外部接口,类的成员函数的定义看成是类的内部实现。写程序的时候只需要外部接口也就是头文件即可,这一特点和我们使用标准库函数的道理是一致的,因为在类的定义中,已经包含了成员函数(方法)的声明。

问题二

域区分符和外部全局变量和类成员变量之间的关系。

在上面的代码中我们看到了,外部全局和类内部都有一个叫做pp的整形变量,那么我们要区分操作他们用什么方法呢?

使用域区分符就可以做到这一点,在上面的代码中::pp=11;操作的就是外部的同名称全局变量,pp=100;操作的就是类内部的成员变量,这一点十分重要!

问题三

一个类的所有对象调用的都是同一段代码,那么操作成员变量的时候计算机有是如何知道哪个成员是属于哪个对象的呢?
这里牵扯到一个隐藏的this指针的问题,上面的代码在调用a.rp()的的时候,系统自动传递一了个a对象的指针给函数,在内部的时候pp=100;的时候其实就是this->pp=100;

所以你把上面的成员函数写成如下形势也是正确的:

void test::rp()
{
::pp=11;
this->pp=100;//this指针就是指向a对象的指针
}

 

类的成员函数和普通函数一样是可以进行重载操作的,关于重载函数前面已经说过,这里不

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,