c++ const放置的位置
标准中int const a 与 const int a 是完全等价的。正因为如此,会有很多各种不同的风格,同样的还有“*是跟类型还是变量?”,比如char* p与 char *p,它们是等价的。
是采用const T& t还是 T const& t呢
是采用int* a 还是int *a呢
我在看《C++ Templates中文版》时,它里面特别提到要使用 int const 这种定义,函数参数定义也是这个写的
T addValue(T const& x) {
//
}
如果是string类型,它是这样写的string const& str
这种写法也我觉得很怪异,特别是我见到的大多数C++不是这样定义的。比如我看V8的源码一般是这样定义的:
static bool EnableAgent(const char* name, int port);
static void SendCommand(const uint16_t* command, int length,
ClientData* client_data = NULL);
/**
* Allocates a new string from either utf-8 encoded or ascii data.
* The second parameter 'length' gives the buffer length.
* If the data is utf-8 encoded, the caller must
* be careful to supply the length parameter.
* If it is not given, the function calls
* 'strlen' to determine the buffer length, it might be
* wrong if 'data' contains a null character.
*/
static Local<String> New(const char* data, int length = -1); /** Allocates a new string from utf16 data.*/
static Local<String> New(const uint16_t* data, int length = -1); /** Creates a symbol. Returns one if it exists already.*/
static Local<String> NewSymbol(const char* data, int length = -1);
我看陈硕老师的muduo源码也是上面这种风格:
//https://github.com/chenshuo/muduo/blob/master/muduo/net/Socket.cc
void Socket::bindAddress(const InetAddress& addr)
{
sockets::bindOrDie(sockfd_, addr.getSockAddrInet());
}
void Socket::listen()
{
sockets::listenOrDie(sockfd_);
}
int Socket::accept(InetAddress* peeraddr)
{
struct sockaddr_in addr;
bzero(&addr, sizeof addr);
int connfd = sockets::accept(sockfd_, &addr);
if (connfd >= 0)
{
peeraddr->setSockAddrInet(addr);
}
return connfd;
}
而我看lua的源码(C语言的),是这样定义的:
static int handle_luainit (lua_State *L) {
const char *init = getenv(LUA_INIT);
if (init == NULL) return 0; /* status OK */
else if (init[0] == '@')
return dofile(L, init+1);
else
return dostring(L, init, "=" LUA_INIT);
}
struct Smain {
int argc;
char **argv;
int status;
};
static int pmain (lua_State *L) {
struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
char **argv = s->argv;
int script;
int has_i = 0, has_v = 0, has_e = 0;
globalL = L;
if (argv[0] && argv[0][0]) progname = argv[0];
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0);
s->status = handle_luainit(L);
if (s->status != 0) return 0;
script = collectargs(argv, &has_i, &has_v, &has_e);
if (script < 0) { /* invalid args? */
print_usage();
s->status = 1;
return 0;
}
if (has_v) print_version();
s->status = runargs(L, argv, (script > 0) ? script : s->argc);
if (s->status != 0) return 0;
if (script)
s->status = handle_script(L, argv, script);
if (s->status != 0) return 0;
if (has_i)
dotty(L);
else if (script == 0 && !has_e && !has_v) {
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
return 0;
}
上面很明显是C与C++不同的风格。后来通过搜索,发现wiki百科里有关于const的一些详细说明:
https://en.wikipedia.org/wiki/Const_(computer_programming)
不过*与类型靠在一起还是与指针变量靠在一起,我发现Facebook中同一个cpp中就存在二种不同的形式:
https://github.com/facebook/hhvm/blob/master/hphp/compiler/builtin_symbols.cpp
cocos2d-x的官方源码也有这个问题:
https://github.com/cocos2d/cocos2d-x/blob/v3/cocos/2d/CCLayer.cpp
C中的习惯 int *ptr,说明*ptr是一个int类型,ptr是指定int的一个指针
int const *ptr 说明*ptr是一个常量,一个int型的常量
int * const ptr ptr是一个常量,一指针类型(int *)的常量
C++将*与类型关联起来,比如 int* a,所有就出现了上面C++的那种风格。在c++中为了避免疑惑,虽然const int* p与int const* p等价,但为了防止与int * const p太过相似,我觉得还是采用const int* p这种比较适合(语义上int const表达更为适合,表示const是限定int的)。int* const p来定义指针常量。
表达的意思:*(指针)与 const(常量限定符)谁在前面先读谁,* 象征着地址,const 象征着内容。
const int * p 常量指针,p是指针,指向常量的指针。
常量const在前 *指针在后,const 限定 * ,所以不能使用*p = xx进行修改,但是可以通过p = &b来修改指针变量的值。
int* const p 指针常量,p是指针,是一个常量的指针,地址不允许被修改,所以p = &b是非法的,但是可以改变它指向的值 *p = b;
p永远是指针,给指针赋值使用&取地址的操作符,如果const 在 p之前,说明它是一个(常量的)指针,其值是不能变化的
最近在看《C++编程思想》里面单独有一章写const,刚看一点就联想起之前看的《C++ Template中文》后有些困惑。现在理清楚了,反而觉得比较轻松。里面提到C 与 C++在const的处理上还是有区别的,这里我还没完全理解透彻,等完全搞明显了可能会再写一篇文章。
c++ const放置的位置的更多相关文章
- 【转】【Python + selenium】linux和mac环境,驱动器chromedriver和测试报告HTMLTestRunner放置的位置
感谢: 作者:gz_tester,文章:<linux和mac环境,chromedriver和HTMLTestRunner放置的位置> 使用场景 配置python selenium 环境 使 ...
- c++ const 修饰变量位置含义
c++ const 修饰变量位置含义 const 修饰成员变量 const修饰指针变量时: 只有一个const,如果const位于*左侧,表示指针所指数据是常量,也就是指向常量的指针,不能通过解引用修 ...
- script放置最佳位置(转载)
html文件是自上而下的执行方式,但引入的css和javascript的顺序有所不同,css引入执行加载时, 程序仍然往下执行,而执行到<script>脚本是则中断线程,待该script脚 ...
- JavaScript脚本在页面中放置的位置
JavaScript脚本通常放置在三个位置: 1.head部分JavaScript脚本. 2.body部分JavaScript脚本. 3.单独以.js结尾的文件中的JavaScript脚本. 客户端会 ...
- JavaScript入门:002—JS代码放置的位置
JavaScript在页面中使用,那么这些JS代码应该放在什么位置呢?以下来看一下. 一般来说有两种方式.写在界面上和使用.js文件.1.1界面上的Head部分能够直接放在head标签内,例如以下代码 ...
- javascript代码放置位置对程序的影响
在编写html文档时,javascript可以放置的位置有两个地方<head>或者<body>,但是放置的地方,会对 JavaScript 代码的正常执行会有一定影响.由于 H ...
- javascript标签放置位置
首先:放置位置哪里都能放 但是js代码很有可能不起作用:例如:往id为span的标签中定时插入数字 var time=document.getElementById("span") ...
- 更改android AVD模拟器创建路径位置的方法
打开:计算机-->系统属性-->环境变量—>在“系统变量”那选择“新建”-->变量名为 "ANDROID_SDK_HOME” (注意,必须为这个名字!),然后把变量值 ...
- iOS 宏(define)与常量(const)的正确使用
在iOS开发中,经常用到宏定义,或用const修饰一些数据类型,经常有开发者不知怎么正确使用,导致项目中乱用宏与const修饰 你能区分下面的吗?知道什么时候用吗? #define HSCoder @ ...
随机推荐
- 【笔记】Python 学习Tips
Lambda Python中给予的定义是用来创建匿名的简单函数(单行).基本的应用场景就是替换简单函数的定义. >>> fl = lambda x : x % 3 >>& ...
- SublimeText为啥选择Python开发extension
真正优秀的软件是靠优秀的程序员开发出来的,反过来也一样,优秀的语言,平台,工具只有在优秀的程序员的手中才能显现出它的威力. 比如,Jon Skinner开发的SublimeText.桌面应用一般支持二 ...
- poj 3259 Wormholes 判断负权值回路
Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...
- .NET Socket服务编程之-高效连接接入编
在.NET上编写网络服务深入都有2,3年了,而这些时间时如何在.NET里实现网络服务积累了一些经验.在接下来的时间里会把这方面的经验通过博客的方式分享出来.而这一章主要是讲解在如果提高服务连接接入的效 ...
- C#函数式编程之惰性求值
惰性求值 在开始介绍今天要讲的知识之前,我们想要理解严格求值策略和非严格求值策略之间的区别,这样我们才能够深有体会的明白为什么需要利用这个技术.首先需要说明的是C#语言小部分采用了非严格求值策略,大部 ...
- zlib的安装
wget http://www.zlib.net/zlib-1.2.8.tar.gz tar -zxvf zlib-1.2.8.tar.gz cd zlib-1.2.8 ./configure mak ...
- JBoss无规律自动关闭故障定位
转载地址:http://blog.knowsky.com/264489.htm 最近遇到了几次JBoss无规律自动关闭的奇怪现象,通过history历史命令和last登录信息,都看不到有人操作过的迹象 ...
- 创建一个简单的HTTP服务(自动查找未使用的端口)
var t = new Thread(new ThreadStart(() => { HttpListener listener = new HttpListener(); var prefix ...
- 带你看懂Dictionary的内部实现
了解Dictionary的开发人员都了解,和List相比,字典添加会慢,但是查找会比较快,那么Dictionary是如何实现的呢? Dictionary的构造 下面的代码我看看Dictionary在构 ...
- java包装类的作用
转载自http://zhidao.baidu.com/question/2052192149152534987.html 第一,基本数据类型之间的相互转换不是都可以制动转换的,而你强制转换又会出问题, ...