(原創) 如何在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++,我們會這樣寫
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
12using namespace std;
13
14void func(const string& s) {
15 // s = "new"; // error!!
16 cout << s << endl;
17}
18
19int main() {
20 string s = "old";
21 func(s);
22 cout << s << endl;
23}
執行結果
old
但在C++/CLI,寫法卻不一樣
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
11using namespace System;
12
13void func(String^ const% s) {
14 s = "new"; // error!!
15 Console::WriteLine(s);
16}
17
18int main() {
19 String^ s = "old";
20 func(s);
21 Console::WriteLine(s);
22}
執行結果
old
至於為什麼C++/CLI設計的理念要將const放在中間,而不是如ISO C++放在前面,詳細原因我並不清楚,不過由於String^本身是個handle(可以想做.NET的pointer),若只寫
是對handle做一次copy constructor,為了要節省copy的動作,所以使用pass by reference of handle
而今天我們要const的,是reference,而非handle,所以若依照ISO C++的寫法
由於const較接近handle,semantics似乎較接近『將handle宣告為const』,但很遺憾C++/CLI並不允許這樣的寫法,若改成
由於較接近reference,其semantics較接近我們要的『將reference宣告為const』,這正是C++/CLI要的。
Conclusion
C++/CLI是個好語言,將C++提升到了managed境界,並且改進了不少語法,基本上native的部份,ISO C++都可以繼續用,但managed的部份,語法則有些小差異。