如何取消函数原型对函数参数传递方式三种的控制

详解C++编程中向函数传递引用参数的用法
转载 &更新时间:日 16:09:42 & 投稿:goldensun
这篇文章主要介绍了详解C++编程中向函数传递引用参数的用法,包括使函数返回引用类型以及对指针的引用,需要的朋友可以参考下
引用类型的函数参数
向函数传递引用而非大型对象的效率通常更高。 这使编译器能够在保持已用于访问对象的语法的同时传递对象的地址。 请考虑以下使用了 Date 结构的示例:
// reference_type_function_arguments.cpp
struct Date
short DayOfW
// Create a Julian date of the form DDDYYYY
// from a Gregorian date.
long JulianFromGregorian( Date& GDate )
static int cDaysInMonth[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
long JDate = 0;
// Add in days for months already elapsed.
for ( int i = 0; i & GDate.Month - 1; ++i )
JDate += cDaysInMonth[i];
// Add in days for this month.
JDate += GDate.D
// Check for leap year.
if ( GDate.Year % 100 != 0 && GDate.Year % 4 == 0 )
// Add in year.
JDate *= 10000;
JDate += GDate.Y
int main()
前面的代码显示通过引用传递的结构的成员是通过成员选择运算符 (.) 访问的,而不是通过指针成员选择运算符 (–&) 访问的。
尽管作为引用类型传递的参数遵循了非指针类型的语法,但它们仍然保留了指针类型的一个重要特征:除非被声明为 const,否则它们是可以修改的。 由于上述代码的目的不是修改对象 GDate,因此更合适的函数原型是:
long JulianFromGregorian( const Date& GDate );
此原型将确保函数 JulianFromGregorian 不会更改其参数。
任何其原型采用引用类型的函数都能接受其所在位置的相同类型的对象,因为存在从 typename 到 typename& 的标准转换。
引用类型函数返回
可将函数声明为返回引用类型。 做出此类声明原因有:
返回的信息是一个返回引用比返回副本更有效的足够大的对象。
函数的类型必须为左值。
引用的对象在函数返回时不会超出范围。
就像通过引用传递大型对象 to 函数或返回大型对象 from 函数可能更有效。 引用返回协议使得不必在返回前将对象复制到临时位置。
当函数的计算结果必须为左值时,引用返回类型也可能很有用。 大多数重载运算符属于此类别,尤其是赋值运算符。 重载运算符在重载运算符中有述。
请考虑 Point 示例:
// refType_function_returns.cpp
// compile with: /EHsc
#include &iostream&
class Point
// Define "accessor" functions as
// reference types.
unsigned& x();
unsigned& y();
// Note that these are declared at class scope:
unsigned obj_x;
unsigned obj_y;
unsigned& Point :: x()
return obj_x;
unsigned& Point :: y()
return obj_y;
int main()
Point TheP
// Use x() and y() as l-values.
ThePoint.x() = 7;
ThePoint.y() = 9;
// Use x() and y() as r-values.
cout && "x = " && ThePoint.x() && "\n"
&& "y = " && ThePoint.y() && "\n";
请注意,函数x 和 y 被声明为返回引用类型。 这些函数可在赋值语句的每一端上使用。
另请注意在 main 中,ThePoint 对象停留在范围中,因此其引用成员仍处于活动状态,可以安全地访问。
除以下情况之外,引用类型的声明必须包含初始值设定项:
显式 extern 声明
类成员的声明
类中的声明
函数的参数或函数的返回类型的声明
返回局部变量地址时的注意事项
如果在局部范围中声明某个对象,则该对象会在函数返回时销毁。 如果函数返回对该对象的引用,则当调用方尝试使用 null 引用时,该引用可能会在运行时导致访问冲突。
// C4172 means Don't do this!!!
Foo& GetFoo()
} // f is destroyed here
编译器会在这种情况下发出警告:警告 C4172: 返回局部变量或临时变量的地址。 在简单程序中,如果调用方在覆盖内存位置之前访问引用,则有时可能不会发生访问冲突。 这纯属运气。 请注意该警告。
对指针的引用
声明对指针的引用的方式与声明对对象的引用差不多。声明对指针的引用将生成一个可像常规指针一样使用的可修改值。
以下代码示例演示了使用指向指针的指针与使用对指针的引用之间的差异。
函数 Add1 和 Add2 在功能上是等效的(虽然它们的调用方式不同)。二者的差异在于,Add1 使用双间接寻址,而 Add2 利用了对指针的引用的便利性。
// references_to_pointers.cpp
// compile with: /EHsc
#include &iostream&
#include &string&
// STL namespace
sizeOfBuffer = 132
// Define a binary tree structure.
struct BTree {
// Define a pointer to the root of the tree.
BTree *btRoot = 0;
int Add1( BTree **Root, char *szToAdd );
int Add2( BTree*& Root, char *szToAdd );
void PrintTree( BTree* btRoot );
int main( int argc, char *argv[] ) {
// Usage message
if( argc & 2 ) {
cerr && "Usage: Refptr [1 | 2]" && "\n";
cerr && "\nwhere:\n";
cerr && "1 uses double indirection\n";
cerr && "2 uses a reference to a pointer.\n";
cerr && "\nInput is from stdin.\n";
char *szBuf = new char[sizeOfBuffer];
if (szBuf == NULL) {
cerr && "Out of memory!\n";
return -1;
// Read a text file from the standard input device and
// build a binary tree.
//while( !cin.eof() )
cin.get( szBuf, sizeOfBuffer, '\n' );
cin.get();
if ( strlen( szBuf ) ) {
switch ( *argv[1] ) {
// Method 1: Use double indirection.
Add1( &btRoot, szBuf );
// Method 2: Use reference to a pointer.
Add2( btRoot, szBuf );
cerr && "Illegal value '"
&& *argv[1]
&& "' supplied for add method.\n"
&& "Choose 1 or 2.\n";
return -1;
// Display the sorted list.
PrintTree( btRoot );
// PrintTree: Display the binary tree in order.
void PrintTree( BTree* MybtRoot ) {
// Traverse the left branch of the tree recursively.
if ( btRoot-&Left )
PrintTree( btRoot-&Left );
// Print the current node.
cout && btRoot-&szText && "\n";
// Traverse the right branch of the tree recursively.
if ( btRoot-&Right )
PrintTree( btRoot-&Right );
// Add1: Add a node to the binary tree.
Uses double indirection.
int Add1( BTree **Root, char *szToAdd ) {
if ( (*Root) == 0 ) {
(*Root) = new BT
(*Root)-&Left = 0;
(*Root)-&Right = 0;
(*Root)-&szText = new char[strlen( szToAdd ) + 1];
strcpy_s((*Root)-&szText, (strlen( szToAdd ) + 1), szToAdd );
if ( strcmp( (*Root)-&szText, szToAdd ) & 0 )
return Add1( &((*Root)-&Left), szToAdd );
return Add1( &((*Root)-&Right), szToAdd );
// Add2: Add a node to the binary tree.
Uses reference to pointer
int Add2( BTree*& Root, char *szToAdd ) {
if ( Root == 0 ) {
Root = new BT
Root-&Left = 0;
Root-&Right = 0;
Root-&szText = new char[strlen( szToAdd ) + 1];
strcpy_s( Root-&szText, (strlen( szToAdd ) + 1), szToAdd );
if ( strcmp( Root-&szText, szToAdd ) & 0 )
return Add2( Root-&Left, szToAdd );
return Add2( Root-&Right, szToAdd );
用法:Refptr [1 | 2]
1 使用双间接寻址
2 使用对指针的引用。输入来自 stdin。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具在vc中,在调用一个函数之前,必须有该函数的声明(或定义),可能是包含在了头文件中,也可能是在源文件中进行了显式的声明。但在嵌入式编程中,在链接其它模块的函数时,往往不经过函数的声明,就可以调用其它模块的函数。如模块A定义了函数void moduleA_func(float x, float y),并生成了.a文件。此时,只要在makefile中指定了链接该.a文件,模块B就可以直接调用该函数而无需进行声明,如:
void moduleB_func()
moduleA_func(x, y);。。。
就是因为没有对该函数原型进行声明,造成了一个问题,调了一天多都没有调出来。最后没想到是因为参数传递时产生了错误,使坐标完全不对而图像绘制不出来。思考了硬件的问题,软件的问题,编译环境的问题,没想到阴沟里翻了船,被小小的c语言语法给捉弄了。勿以事小而不为啊,函数声明可以发现编译方面的问题(甚至有些编译警告也得重视),也可以避免调用错误。
extern void moduleA_func(float x, float y);
void moduleB_func()
x=y=100.0;
moduleA_func(x, y);。。。
& 著作权归作者所有
人打赏支持
码字总数 55732
高级程序员
PHP压缩html网页代码 (清除空格,换行符,制表符,注释标记)。 有个不错的方法就是压缩HTML,压缩html 其实就是:清除换行符,清除制表符,去掉注释标记 。它所起到的作用不可小视。 现提供PHP...
//构造函数应该是(空的)结构框架function box(){}; //原型属性和方法——构造函数赋予原型prototype结构,(box.prototype.box.prototype.run=function(){}); //原型属性和方法——特征是...
对象 概述 对象可简单理解为一个字典: key为字符串属性, 值为任意一个变量或对象. 对象是可变的, 我们通过引用而非值来操作对象(所以可使用Object.assign({}, o)来提供对象o的一个副本) 每个...
持续更新,直到看完,中间如果有什么纪录不对或者有疑问的,还希望和大家一起讨论
在ECMAScript 5中,字符串可以当作只读数组,除了用charAt()方法,也可以用括号来访问字符串中的...
邪气小生 ?
偶然看到JavaScript Tips。这个项目是每天分享一个JavaScript Tip,受到这个项目的启发,我也打算每天更新一个小Tip,我会参考原文,如果觉得写的很不错,我也会仅仅充当翻译工,但是每一个T...
小马_wolf ?
javascript有5种基础的内建对象(Fundamental Objects),、、、、,而/尤为特殊,是定义其他内建对象或者普通对象和方法的基础。 详细的了解和对象有助于更好的理解javascript的一些工作原理。...
伟林 ? 前天 ?
本文篇幅较长,有兴趣的可以先收藏再看。本文将重要的 ES6 特性介绍了一遍,并且详细解释了一些重难点。 let && const 与 的声明用法相同,但是多了一个临时死区(Temporal Distonrtion Zone...
与获取进程相关信息的操作,都在unistd.h文件中,常用的有如下一些函数。 getuid 函数原型:uid_t getuid(void); 函数功能:获取调用进程的用户的ID。 函数返回:调用进程的用户的ID。 声明文...
晨曦之光 ?
一.原型链指针(prototype)的特点 1.原型对象(prototype): (本质是一个对象,每一个函数在创建函数时,都是由Function这个对象产生一个原型对象,然后通过指针的方式赋给对象)是函数对象...
奋斗的小芋头 ?
理解关于Function的原型链问题 关于Function的原型链问题的一些个人粗略理解,欢迎指正错误的地方 要理解Function的原型链的问题 首先深入理解 的含义是 实例对象指向实例原型!! 实例的原型对...
马涛涛_风 ? 05/10 ?
没有更多内容
加载失败,请刷新页面
一、java能做什么 除了硬件设备接口之外,所有PB/VB/C#/Delphi等高级语言能做的事情,Java都能做,而且因为JAVA具有丰富的开源项目,还具有广大高级语言所不能做的事情,主要包括如下几大应用...
恋码之子 ? 9分钟前 ?
1. 常用框架 框架 阿里 fastjson 谷歌 gson JavaBean序列化为Json,性能:Jackson & FastJson & Gson & Json-lib 2. Jackson 处理相关结果 1. 指定字段不返回 @JsonIgnpre @JsonIgnorepriv......
影狼 ? 9分钟前 ?
MongoDB 备份(mongodump)与恢复(mongorestore) MongoDB数据备份 在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中。 mongodump命令可以通过参数指定...
linjin200 ? 10分钟前 ?
:绑定变量,而不是到子路由传参的必须写法 const config = { staticHash: false, staticUrl: './', request: '/api', //作为网络请求使用 api: 'http://test.diandanme.com', //网页跳转使用...
大美琴 ? 11分钟前 ?
源码 预览 游戏开发中或多或少都有接触过Tilemap,在Tiled编辑器里编辑好地图之后,导出数据,然后在游戏引擎(Cocos...)里就可以直接使用了,确实很方便。 由于Pixi.js自身并不支持Tilemap的...
雨里有条鱼 ? 11分钟前 ?
xiaomin0322 ? 11分钟前 ?
1、 2、 3、
moon888 ? 13分钟前 ?
今天客户突然来找我说服务器起不来了,启动报错,我一看不得了,这可是大事,还好客户的系统面向内部,使用的人比较少,于是我让他们把日志发给我,经过查看日志,发现一段java报错日志: Ca...
吃兔纸不吐毛 ? 14分钟前 ?
孟飞阳 ? 18分钟前 ?
昨日在国外安全社区seclists有一个署名叫Rose Jackcode的白帽子公布了微信支付sdk的一个严重的安全漏洞(xxe漏洞)。攻击者可以伪造一个恶意的回调数据请求(xml格式),读取商户服务器上任意文件...
hxt168 ? 28分钟前 ?
没有更多内容
加载失败,请刷新页面
文章删除后无法恢复,确定取消删除此文章吗?
亲,自荐的博客将通过私信方式通知管理员,优秀的博客文章审核通过后将在博客推荐列表中显示
确定推荐此文章吗?
确定推荐此博主吗?
聚合全网技术文章,根据你的阅读喜好进行个性推荐
指定官方社区
深圳市奥思网络科技有限公司版权所有C++中类对象传递作参数的函数原型的编写
今天编写一个小程序时遇到了一个问题,花了一下午终于解决了
3.编写一个C++程序,它使用3个用户定义的函数(包括main()),并生成下面的输出:
Three blind mice
Three blind mice
See how they run
See how they run
在使用函数原型传递一个字符串常量时,老是出错,一开始是:string is not declared in this
scope,我明明包括了#include&string&,并且在使用时 string
,为什么还会出现这种情况了,后来上网一搜原来是要在前面加上std::string
这样定义,因为自己没有在预编译头文件中加如果加了这句就可以直接使用string
类了,言归正传,函数原型一开始为void mice(string);提示错误,后来改为void mice(string
*);也提示错误,最后改成void mice (string
&);也出现错误,因为我传递的是"Three" 这样一个字符串常量,因此正确的函数原型应为:void
mice(const string &);
程序如下:
#include&iostream&
void mice(const string&
void print();
int main()
& mice("Three");
& print();
& cin.get();
& return 0;
void mice(const string & s)
cout&&s&&"
blind mice"&&
cout&&s&&"
blind mice"&&
void print()
& cout&&"See how
they run"&&
& cout&&"See how
they run"&&
总结起来就是:将类对象如string,ostream,istream,ofstream,ifstream等类对象作为函数参数时,常用引用对象来实现
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。如何阅读函数的定义(函数原型)
如何阅读函数的定义(函数原型)
文档中的每个函数都有快速参考,学会如何阅读和理解文档将使得 PHP 的使用更加简单。和依赖赖于复制/粘贴范例比起来,您一定更希望知道如何阅读函数的定义(函数原型):
先决条件:对“”的基本理解:
尽管 PHP 是亚类型语言,但对“”有一个基本的理解也是非常重要的,因为它们有重要的意义。
函数定义告诉我们函数什么类型的值,让我们用函数
的定义作为我们的第一个范例:
(PHP 3, PHP 4 >= 4.0.0)
strlen -- Get string length
Description
int strlen ( string str )
Returns the length of string.
表格 N-1. 函数定义组成部分说明
(PHP 3, PHP 4 >= 4.0.0)
strlen() 在 PHP 3 和 PHP 4 中都存在
该函数返回的值的类型,这里为整型。(例如,字符串的长度是以数字来衡量的)
( string str )
第一个(本例中是唯一的)参数,在该函数中名为 str,且类型为 。
我们可以将以上函数的定义写成一般形式:
( 参数类型
很多函数都有多个变量,例如 。其函数原型如下:
bool in_array ( mixed needle, array haystack [, bool strict])
这是什么意思? 返回一个“”值,成功(即在参数 haystack 中能找到参数 needle)则返回 TRUE 或者失败(即在参数 haystack 中找不到参数 needle)则返回 FALSE。第一个参数被命名为 needle 且其不定,因此我们将其称为“混和”类型。该混和类型的 needle 参数(我们要找的对象)可以适一个纯量的值(字符串、整数、或者),或者一个。haystack (我们寻找的范围)是第二个参数。第三个可选参数被命名为 strict。所有的可选参数都用 [ 方括号 ] 引用。手册表明 strict 参数默认值为布尔值 FALSE。需要了解函数工作的细节,请参阅手册中和该函数相关的页面。

我要回帖

更多关于 js回调函数 参数传递 的文章

 

随机推荐