(原創) 如何在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
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
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
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
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的部份,語法則有些小差異。

posted on 2007-05-17 16:54  真 OO无双  阅读(1982)  评论(0编辑  收藏  举报

导航