(原創) 如何在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.com3

4
Filename : ConstReference2.cpp5
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++6
Description : Demo how to use pass by reference to const7
Release : 05/17/2007 1.08
*/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,寫法卻不一樣
/* 2
(C) OOMusou 2006 http://oomusou.cnblogs.com3

4
Filename : ConstReference.cpp5
Compiler : Visual C++ 8.0 / C++/CLI6
Description : Demo how to use pass by reference to const7
Release : 05/17/2007 1.08
*/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的部份,語法則有些小差異。

浙公网安备 33010602011771号