C++函数的声明和定义定义声明

我们已经学会如何调用成员函数,那么成员函数又是如何声明和定义的呢?它和普通函数有着什么异同点呢?
普通函数在使用之前必须声明和定义,成员函数也是这样。不过成员函数是属于某一个类的,所以只能在类的内部声明,即在定义类的时候写明成员函数的函数原型,同时要注意此函数是公有的还是私有的。如果一个类的某个成员函数是私有的,那么它只能被这个类的其他成员函数调用。成员函数的函数原型和普通函数的函数原型在写法上是一样的。比如:
class Node//定义一个链表结点类
& &public:
& &int readi();//通过该函数读取idata
& &char readc();//通过该函数读取cdata
& &bool seti(int i);//通过该函数修改idata
& &bool setc(char c);//通过该函数修改cdata
& &bool setp(Node *p);//通过该函数设置前驱结点
& &bool setn(Node *n);//通过该函数设置后继结点
& &private:
& &//存储数据保密
& & //存储数据保密
& &Node *//前驱结点的存储位置保密
& &Node *//后继结点的存储位置保密
常成员函数
由于数据封装在类的内部,在处理一些问题的时候就需要小心翼翼,不能把成员数据破坏了。以前我们介绍使用const来保护变量(就变成了常量),或保护指针所指向的内容,那么在类中,我们也可以使用const这个保留字来保护成员数据不被成员函数改变。我们把这种成员函数称为常成员函数。它的写法就是在函数的参数表后面加上一个const,比如:
& & int readi()//通过该函数读取idata,但不能改变任何成员数据
& & char readc()//通过该函数读取cdata,但不能改变任何成员数据
使用常成员函数,就保证了成员数据的安全,在此函数中任何修改成员数据的语句将被编译器拒之门外。
成员函数的重载
和普通函数类似,在一个类中也可以有成员函数重载。成员函数的重载在规则上和普通函数也并无差别,这里不再赘述。
最终,我们将链表结点类的定义修改如下:&
class Node//定义一个链表结点类
& &public:
& &int readi()//通过该函数读取idata,但不能改变任何成员数据
& &char readc()//通过该函数读取cdata,但不能改变任何成员数据
& &bool set(int i);//重载,通过该函数修改idata
& &bool set(char c);// 重载,通过该函数修改cdata
& &bool setp(Node *p);//通过该函数设置前驱结点
& &bool setn(Node *n);//通过该函数设置后继结点
& &private:
& &//存储数据保密
& & //存储数据保密
& &Node *//前驱结点的存储位置保密
& &Node *//后继结点的存储位置保密
成员函数的定义
成员函数与普通函数的不同之处,在于成员函数是属于某一个类的,而不能被随意地调用。那么,我们在定义一个成员函数的时候如何来表达它是属于某一个类的呢?这个时候我们就要用到::操作符,它表示该函数是属于某一个类的,称为域解析操作符。因此在类定义结束后,定义一个成员函数的格式如下:
返回值类型类名::函数名(参数表)
事实上,成员函数也是可以在类的定义中定义的(此时不需要域解析操作符),但是从程序的运行效率、可读性、美观性考虑,我们建议将成员函数的定义完全放在类定义的外面。于是,链表结点类和其成员函数的定义如下:
class Node//定义一个链表结点类
& &public:
& &int readi()//通过该函数读取idata,但不能改变任何成员数据
& &char readc()//通过该函数读取cdata,但不能改变任何成员数据
& &bool set(int i);//重载,通过该函数修改idata
& &bool set(char c);//重载,通过该函数修改cdata
& &bool setp(Node *p);//通过该函数设置前驱结点
& &bool setn(Node *n);//通过该函数设置后继结点
& &private:
& &//存储数据保密
& &//存储数据保密
& &Node *//前驱结点的存储位置保密
& &Node *//后继结点的存储位置保密&
};//类定义结束,分号切勿忘记
int Node::readi() const//成员函数readi的定义
char Node::readc() const
bool Node::set(int i)//重载成员函数定义
& &idata=i;
bool Node::set(char c)
& &cdata=c;
bool Node::setp(Node *p)
& &prior=p;
bool Node::setn(Node *n)
& &next=n;
在上面这些成员函数定义中,我们可以看出成员数据(或成员函数)在成员函数中可以直接使用。平时我们使用一个对象的公有成员数据时,我们要写作&对象名.成员数据&,但是在成员函数中不需要也不能那样写。接下来,我们就能尝试一下使用我们编写的类了:(程序14.3)
//main.cpp
#include &iostream&
#include &node.h&//包含我们编写好的链表结点类头文件,必须用双引号
int main()
& &N//创建一个链表结点对象a
& &a.set(1);//设置idata
& &a.set('A');//设置cdata
& &cout &&a.readi() &&
& &cout &&a.readc() &&
& &return 0;
运行结果:
注意这个程序有两个文件,一个是头文件node.h,一个是源文件main.cpp。如果你忘记了如何创建一个头文件,那么请看本书的11.2节。
推荐文章 TOP10  C++中有的东西需要放在可以在.h文件中定义,有的东西则必须放在.cpp文件中定义,有的东西在不同的cpp文件中的名字可以一样,而有的则不能一样
  那么究竟哪些东西可在头文件中定义,声明,哪些东西又必须在.cpp中定义,声明呢?
  *以下所有的讨论都是在全局命名空间中(即不定义自己的namespace)下进行的
  1、在.h中只能声明函数,在.cpp中可以声明与定义函数
  如果在.h中声明并定义一个函数,则该函数只能被#include一次,否则则会出现重定义错误
  #pragma once
  void show()
  #include "1.h"
  #include "1.h"
  error LNK2005: "void __cdecl show(void)" (?show@@YAXXZ) 已经在 a.obj 中定义
  所以要避免在头文件中定义函数
  2、在不同.cpp中定义的函数原型(函数返回值,函数名称,函数参数)不能完全一样,
  比如如果有在两个.cpp文件中均存在
  void show(){};
  会出现重定义错误
  内联函数
  为了确保所有调用该inline函数的文件中的定义一样,所以需要是在.h文件中定义
  注意这里的inline对于编译器来说只是建议性的,关于该内联函数被拒绝会在下一篇文章中介绍
  typedef
  在不同的cpp中可以一样
  1、在.h中只能声明,在.cpp中可以声明与定义一个变量
  如果在.h中的定义一个变量,则该变量被include两次以上时则会出现重定义错误
  2、在不同.cpp中定义的变量的名字与类型不同一样
  1、如果const常量是用常量表达式进行初始化的,则可以在.h中声明与定义
  2、如果const变量是用非常量表达式进行初始化的,那么该变量应该在cpp文件中定义,而在.h文件中进行声明。
  3、不同cpp中以定义名字与类型一样的变量
【】【】【】【】
ISBN编号:&8
出版时间:&2013-3
出版社:&中国人事出版社
定价:¥45 优惠价:¥45&&ISBN编号:&9
出版时间:&2013-4
出版社:&中国人事出版社
定价:¥45 优惠价:¥45&&
????????????
????????????
         Copyright ©
() All Rights Reservedc++编程自定义函数
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
c++编程自定义函数
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口c++:关于类的申明和定义
基本类型变量是声明和定义(初始化)是同时产生的
也就是说那么同时对a进行声明和初始化
&而对象,是声明与定义分开的
如果A就是一个声明,告诉编译器x是一个A类的对象变量,但是不进行初始化
&如果以后,x= new A(); 这就是初始化,分配了空间
同样,A x=new A();这也是声明的同时初始化
还有对于函数(方法):
声明只是写出函数的特性(类型 名称 参数),并没有实际的内容,是告诉编译器有这样的一个函数,在定义的时候把函数全部写清楚
代码如下:
&&&&&& int method(int,int);//这里是类成员函数的申明
&&&&&&& //mehtod成员函数定义
以上代码是类的定义。
在A.cpp里的代码如下:
int A::method(int a,int b){
& return (a+b);
} //这里是类成员函数的定义
类成员函数的定义可以放在类的定义里面,也可以放在类定义外定义
但是一般是放在类的定义外定义
在一个类中,使用一个后面定义的类的时候,也要做申明。
class CO//CObject申明
struct CRuntimeClass
// Attributes
&& & & &LPCSTR m_lpszClassN
&& & & &int m_nObjectS
&& & & &UINT m_wS // schema number of the loaded class
&& & & &CObject* (PASCAL* m_pfnCreateObject)(); // NULL =& abstract class
&& & & &CRuntimeClass* m_pBaseC
&& & & &// CRuntimeClass objects linked together in simple list
&& & & &static CRuntimeClass* pFirstC // start of class list
&& & & &CRuntimeClass* m_pNextC & & & // linked list of registered classes
class CObject
&&CObject::CObject() &{
&& & & & & & & & & & &}
&&CObject::~CObject() {
&& & & & & & & & & & &}
&&virtual CRuntimeClass* GetRuntimeClass()
&&static CRuntimeClass classCO
其中结构体在CObject定义前使用到了CObject了。
所以申明一下,结构体的定义才正确,否则将编译出错。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。trackbacks-0
&&& C++是一种复杂的计算机语言,很多在现代高级语言中已经不需要程序员操心的事情(其实这些事情并没有消失而是由语言本身和运行环境替我们做了)在C++中还需要我们处处留意,以免你写的程序编译不通过或者留下潜在BUG。
&&& 了解C++的人知道它里面有两个术语:声明,定义 很多新出现的高级语言对二者的界面很模糊,申明==定义,但C++中二者不同,而且需要了解他们的概念,否则你的程序很可能无法编译通过,现在我们来了解一下他们。
&&& 定义:就是创建一个对象,并且为他非配对象资源,这个概念比较容易理解。比如说 int a = 1; stirng b("abcd"); 定义是必须的,如果没有定义就无法使用对象。而且同一对象(同一作用范围内的同名同类型)只能定义一次重复定义编译器会报错。
&&& 声明:告诉编译器有这个对象存在,并且可以使用,为了理解这个概念先说说C++的一些编码与编译机制。
&&& C++标准允许将一个系统中得不同部分定义在多个文件中,通过INCLUDE合并在一起使用。那么也就允许头文件A中定义的全局A1对象可以被包含该头文件的源文件B使用,这个概念应该容易理解。在说一下C++的编译机制,C++编译时顺序编译内容的,也就是说编译器会一个一个编译文件,然后根据文件的包含关系再做连接,生成一个可执行文件,假设编译器先编译A文件,发现里面定义了A1对象,然后再编译B文件,发现里面使用了一个叫A1的对象,我们假设编译器可以编译通过这个过程没有问题。 但是C++可能会先编译B文件,发现里面有使用一个叫A1的变量,这个时候A文件还未编译,那么编译就会出错中断,如何才能解决这个问题呢,声明技术就出现了,在编译B时候随便还没有A1这个变量被定义,但是如果我先声明一下A1变量,那么就意味着我告诉编译器:系统中是有一给叫A1的变量存在的,请继续编译,编译器在此打个标签继续编译,等编译到A文件时发现了A1的定义,编译器就找到之前打过标签的A1,设置为这个变量是合法的,然后继续向下编译。假设编译器直到编译完所有文件都没有发现A1,就会报错中断编译就会失败,所以申明的作用非常明显。
&&& 不仅是跨文件中的对象使用需要申明,就是同一文件中申明也有很重要的作用,先看如下代码:
&1&int&fun1()&2&{&3&&&&&return&<span style="color: #;&4&}&&&&&5&&6&int&main()&7&{&8&&&&&fun1();&9&<span style="color: #&&&&&fun2();&//&编译时这里会报错,显示该成员未申明<span style="color: #&}<span style="color: #&<span style="color: #&int&fun2()<span style="color: #&{<span style="color: #&&&&&return&<span style="color: #;<span style="color: #&}
&&& 错误很明显,那为什么会出这个错误呢,因为C++编译时顺序编译的,对文件内容页是从上到下做编译,当编译到主函数时发现fun1()调用,因为这个函数在主函数之前定义了所以正常通过,而fun2()函数此时还未定义,所以报错,解决办法很简单,在调用函数前声明一下就可以了:
<span style="color: #&int&main()<span style="color: #&{<span style="color: #&&&&&fun1();<span style="color: #&<span style="color: #&&&&&int&fun2();&//&该语句表示申明fun2函数<span style="color: #&<span style="color: #&&&&&fun2()<span style="color: #&}
&&& 总而言之在不同文件中定义的共享对象在使用前一定要先声明在使用。在同一文件中使用对象之前还未出现定义语句的对象需要先先声在使用。同一文件中先定义后使用的对象不需要声明可直接使用.
阅读(...) 评论()}

我要回帖

更多关于 函数的声明和定义 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信