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的處理上還是有區別的,這里我還沒完全理解透徹,等完全搞明顯了可能會再寫一篇文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM