C到C++ 快速过度 C 结构体到类.docx

上传人:b****8 文档编号:28323116 上传时间:2023-07-10 格式:DOCX 页数:10 大小:18.38KB
下载 相关 举报
C到C++ 快速过度 C 结构体到类.docx_第1页
第1页 / 共10页
C到C++ 快速过度 C 结构体到类.docx_第2页
第2页 / 共10页
C到C++ 快速过度 C 结构体到类.docx_第3页
第3页 / 共10页
C到C++ 快速过度 C 结构体到类.docx_第4页
第4页 / 共10页
C到C++ 快速过度 C 结构体到类.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

C到C++ 快速过度 C 结构体到类.docx

《C到C++ 快速过度 C 结构体到类.docx》由会员分享,可在线阅读,更多相关《C到C++ 快速过度 C 结构体到类.docx(10页珍藏版)》请在冰豆网上搜索。

C到C++ 快速过度 C 结构体到类.docx

C到C++快速过度C结构体到类

类”这个概念对C++来说意义非凡,与面向对象密不可分。

从这个概念开始,C++比C复杂的一面越加凸显。

还记得C语言中的结构体么?

structPoint{

   doublex;

   doubley;

};

上面的代码是一个“结构体模版”,我们利用它创建了一个叫做Point的类型。

在这之后,我们就可以像声明基本类型的变量一样声明Point类型:

Pointob;

ob叫做结构体Point的一个“实例”。

而当我们intn;的时候,会讲n是int类型的一个“变量”。

 

结构体是一种复合类型,但是它和同样身为复合类型的数组不同:

--数组操作技巧-->

charname[20];

我们这样就声明了一个数组,并且每个name[i](0<=i<20)都是一个独立的char类型的变量。

它们被称为数组的“元素”。

值得一提的是,同一个数组的各个元素所占用的内存空间是连续的。

这使得我们在遍历(检索)整个数组的时候,速度非常的快:

intline[]={2,5,6,7,8,12,-5,-32};      //1

intlen=sizeof(line)/sizeof(int);         //2

for(inti=0;i

   line[i]=-line[i];

上述语句遍历这个数组,并且将每个元素的值都取反。

第1个语句说明,数组可以根据你声明时填写的数据自动分配大小,但是一旦分配,数组的大小就定了。

第2个语句可以直接确定数组中元素的个数,这样就无需一个个数了。

sizeof是一个操作符,用法类似于函数。

当参数是数组名时,将得到整个数组所占内存的字节数;而当参数是类型时,得到的是该类型变量的字节数。

而对于字符串数组,初始化有更方便的方法:

charname[]="AlwaysLaugh";

这样name就会被自动分配成长度13的数组(别忘了'\0')。

除了之前介绍的使用sizeof操作符取元素个数的方法以外,头文件(C++中shi)中的strlen函数可以更方便地取字符串长度:

charname[]="AlwaysLaugh";

intlen=strlen(name);

for(inti=0;i

   name[i]++;

这个代码会把name数组的的每个元素在字符表中“后移”一位。

需要注意的是,strlen只能处理char的字符串数组,对int等不适用。

并且它以字符串末尾的'\0'字符为结束标志,因此取到的往往不是数组大小。

--类-->

现在介绍C++中的“类”这个概念,它和结构体极其相似。

我们先写一个使用结构体的程序:

#include

usingnamespacestd;

structPoint{            // 1结构体的模版

   doublex;      // 成员

   doubley;

};

intmain()

{

   Pointp;            // 2结构体的声明

   p.x=3.2;            // 3结构体的使用

   p.y=8.9;

   cout<<"("<

   return0;

}

结构体的模版和函数的定义性质相同(之后介绍的“类”也同样),只是规定了这个结构体/类的内部结构和工作原理,并不分配内存。

我们在使用结构体对象的时候,总是使用它的成员。

“.”这个操作符用来连接结构体的实例和它的成员。

实例的名称可以自由去定义,就像变量名一样,但是相同类型的实例总是拥有的成员确是完全相同的,都和模版中的一致。

 

即利用相同模版初始化的实例都具有相同的成员。

而当将类引入时,会发生较大的变化:

#include

usingnamespacestd;

classPoint{

private:

    doublex;

    doubley;

public:

    setPoint(doublem,doublen){

        x=m;y=n;

    }

    printPoint(){

        cout<<"("<

    }

};

intmain()

{

    Pointp;

    p.setPoint(3.2,8.9);

    p.printPoint();

    return0;

}

这个程序和用结构体的效果是相同的,但是复杂的地方集中在了类的模版定义部分。

出现了很多陌生的东西,private,public,甚至还有函数。

这是因为,对于类而言,不仅变量可以作为成员,函数也可以。

而当你想要在主函数中使用如下语句时:

p.x=2.2;p.y=1.1;

你会发现这个不允许的。

原因就在于关键字private(私有的),它将x和y成员保护了起来,使它们在“模版区”之外不能出现。

注意是“不能出现”,而不仅是“不能赋值”。

这意味着cout<

关键字public(公有的)定义的成员可以暴露给外界,正如主函数中的p.setPoint(3.2,8.9);和p.printPoint();一样。

把x和y设置为私有成员是为了数据的安全性:

intmain()

{

    Pointp;

    p.setPoint(3.2,8.9);

    p.printPoint();

    return0;

}

这是刚刚的主函数,我们从中根本看不出p这个类含有哪种或者多少个私有成员,更不知道成员叫做x/y。

它们确实可以在类模版中看到,但是在工程中我们使用的类,大多数是见不到类模版的,他们存放在不同的文件中。

这样,我们只需要知道类的公有成员函数接受哪些变量,起到哪些作用,学会调用即可。

至于具体细节,内部逻辑,我们不需要知道。

这就是“封装”,C++的三大特性之一。

正如你看到的,私有成员变量可以在成员函数中直接出现,因为它们处于同一个作用域中(类模版的花括号)。

有私有成员函数吗?

当然有。

它可以供其他私有成员函数或者公有成员函数去调用。

总之,只有公有成员(可以出现在“模版区”之外)才会和“.”连用。

因为一个“实例”的声明和使用都是在外界的。

简而言之:

成员包括私有成员和公有成员。

成员分为成员变量和成员函数。

 

--构造函数-->

classPoint{

private:

    doublex;

    doubley;

public:

    Point(){

    }

    

    Point(doublem,doublen){

        x=m;y=n;

    }

    

    setPoint(doublem,doublen){

        x=m;y=n;

    }

    

    printPoint(){

        cout<<"("<

    }

};

仍然是那个类,多了两个比较怪异的函数。

没错,函数的名称和类名称一样,并且他们不含返回值。

有了它们,我们便可以在主函数中这样子声明p。

intmain()

{

    Pointp(3.2,8.9);

    p.printPoint();

    return0;

}

构造函数是在初始化实例的过程中调用的,这样我们可以在初始化的同时给成员赋值,而setPoint用来改变成员的值。

为什么Point函数声明了两次?

还记得函数重载么?

我们重载了它。

这样我们既可以在声明实例的时候初始化它,也可以不这么做。

因为构造函数总是会执行的。

Pointp;和Pointp();丝毫没有区别。

 

--些许复杂的示例程序-->

#include

#include

usingnamespacestd;

structFriend{

    charname[20];

    Friend*nest;

    Friend(char*pn){

        strcpy(name,pn);

        nest=NULL;

    }

};

structFriendList{

    Friend*head;

    Friend*mov;

    intnumber;

    boolnone;

    FriendList(Friend*pri){

        head=mov=pri;

        number=1;

        none=0;

    }

    

    voidReTop(){

        mov=head;

        none=0;

    }

    voidBeFriend(Friend*someone){

        Friend*temp=mov->nest;

        mov->nest=someone;

        someone->nest=temp;

        number++;

    }

    boolQue(Friend*f){

        if(none){

            cout<<"Yougotnofriends.\n\n";

            ReTop();

            return0;

        }

        if(!

mov->nest)none=1;

        charch;

        while(getchar()!

='\n')continue;

        cout<<"Doyouwangtomakefriendswith"

            <name<<"?

"<

            <<"YtoYESandNtoNO"<

        cin>>ch;

        if(ch=='Y'){

            cout<<"You'vebeenfriendwith"<name<<"!

\n\n";

            BeFriend(f);

            ReTop();

            return0;

        }else{

            mov=mov->nest;

            return1;

        }

    }

    voidEnd()

    {

        Friend*temp;

        while(number--){

            temp=head->nest;

            delete(head);

            head=temp;

        }

    }

};

intmain()

{

    charname[20]="AlwaysLaugh";

    Friend*Me=newFriend(name);

    FriendListmyFriend(Me);

    intT=4;

    while(T--){

        cout<<"Enteryourname:

";

        cin>>name;

        Friend*you=newFriend(name);

        cout<<"Hello"<name<<"!

"<

        while(myFriend.Que(you));

    }

    return0;

}

这个示例程序对刚接触C++的人来说难度很大,接近一个课设。

因为类的内部联系复杂。

并且还用到了动态内存分配(比如new和delete操作符),和链表的内容(这些内容对大家来说是陌生的)。

这是一个交朋友的程序,大家不妨编译运行一下,看看效果,再尽力把代码搞懂(为了避免越界访问,请不要输入得太古怪)。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1