如何在C++/CLI實做pass by reference to const? (.NET) (C++/CLI) (C/C++)

Abstract
C++ programmer都知道用pass by reference to const取代pass by value,但C++/CLI該怎麼實做呢?

Introduction
使用pass by reference to const而不使用pass by value,理由Scott Meyers在Effective C++ 3/e Item 20講的很清楚,我就不再重複,主要有兩個優點:
1.避免pass by value多次觸發copy constructor和destructor。
2.避免在polymorphism時的object slicing。

在ISO C++,我們會這樣寫

 1 /* 
 2(C) OOMusou 2007 http://oomusou.cnblogs.com
 3
 4Filename    : ConstReference2.cpp
 5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
 6Description : Demo how to use pass by reference to const
 7Release     : 05/17/2007 1.0
 8*/

 9 #include  < iostream >
10 #include  < string >
11
12 using   namespace  std;
13
14 void  func( const   string &  s)  {
15  // s = "new"; // error!!
16  cout << s << endl;
17}

18
19 int  main()  {
20  string s = "old";
21  func(s);
22  cout << s << endl;
23}


執行結果

old
old


但在C++/CLI,寫法卻不一樣

 1 /* 
 2(C) OOMusou 2006 http://oomusou.cnblogs.com
 3
 4Filename    : ConstReference.cpp
 5Compiler    : Visual C++ 8.0 / C++/CLI
 6Description : Demo how to use pass by reference to const
 7Release     : 05/17/2007 1.0
 8*/

 9 #include  " stdafx.h "
10
11 using   namespace  System;
12
13 void  func(String ^   const %  s)  {
14  s = "new"// error!!
15  Console::WriteLine(s);
16}

17
18 int  main()  {
19  String^ s = "old";
20  func(s);
21  Console::WriteLine(s);
22}


執行結果

old
old


至於為什麼C++/CLI設計的理念要將const放在中間,而不是如ISO C++放在前面,詳細原因我並不清楚,不過由於String^本身是個handle(可以想做.NET的pointer),若只寫

void  func(String ^  s)  {}


是對handle做一次copy constructor,為了要節省copy的動作,所以使用pass by reference of handle

void  func(String ^&  s)  {}


而今天我們要const的,是reference,而非handle,所以若依照ISO C++的寫法

void  func( const  String ^%  s)  {}


由於const較接近handle,semantics似乎較接近『將handle宣告為const』,但很遺憾C++/CLI並不允許這樣的寫法,若改成

void  func(String ^   const%  s)  {}


由於較接近reference,其semantics較接近我們要的『將reference宣告為const』,這正是C++/CLI要的。

Conclusion
C++/CLI是個好語言,將C++提升到了managed境界,並且改進了不少語法,基本上native的部份,ISO C++都可以繼續用,但managed的部份,語法則有些小差異。

你可能感兴趣的:(reference)