﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-弄错的车站</title><link>http://www.cppblog.com/golq/</link><description>孤独自由的旅人啊，
    亲吻着睡梦中的她，
        她的眼泪慢慢就变成了一朵花。</description><language>zh-cn</language><lastBuildDate>Sat, 04 Apr 2026 20:06:10 GMT</lastBuildDate><pubDate>Sat, 04 Apr 2026 20:06:10 GMT</pubDate><ttl>60</ttl><item><title>C++/CLI学习入门(十):类的运算符重载</title><link>http://www.cppblog.com/golq/archive/2009/07/22/90790.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Tue, 21 Jul 2009 16:30:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/22/90790.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/90790.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/22/90790.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/90790.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/90790.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt"> C++/CLI中可以对运算符进行重载，但与本地C++有所区别。同时对于运算符重载，数值类和引用类也存在不同要求。下面以例子开始，了解C++/CLI中重载运算符的方法。</p> <h1> 一、数值类中重载运算符</h1> <p style="text-indent: 24pt">下面的例子重载了加法运算符。</p><pre>value <span style="color: #0000ff">class</span> Length
{
<span style="color: #0000ff">private</span>:
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;

<span style="color: #0000ff">public</span>:
	<span style="color: #0000ff">static</span> initonly <span style="color: #0000ff">int</span> inchesPerFoot = 12;
	
	Length(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) : feet(ft), inches(ins) {}
	
	<span style="color: #0000ff">virtual</span> String^ ToString() override
	{ <span style="color: #0000ff">return</span> feet+L"<span style="color: #8b0000"> feet </span>"+inches+L"<span style="color: #8b0000"> inches</span>"; }

	Length <span style="color: #0000ff">operator</span>+(Length len)
	{
		<span style="color: #0000ff">int</span> inchTotal = inches + len.inches + inchesPerFoot*(feet + len.feet);
		<span style="color: #0000ff">return</span> Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot);
	}
};</pre>
<p style="text-indent: 24pt"> 类的使用很简单，方法如下</p><pre>Length len1 = Length(6, 9);
Length len2 = Length(7, 8);
Console::WriteLine(L"<span style="color: #8b0000">{0} plus {1} is {2}</span>", len1, len2, len1+len2);</pre>
<p style="text-indent: 24pt"> 上面重载的加法运算符也可通过静态成员的方式实现。</p><pre><span style="color: #0000ff">static</span> Length <span style="color: #0000ff">operator</span>+(Length len)
{
	<span style="color: #0000ff">int</span> inchTotal = inches + len.inches + inchesPerFoot*(feet + len.feet);
	<span style="color: #0000ff">return</span> Length(inchTotal/inchesPerFoot, inchTotal%inchesPerFoot);
}</pre>
<p style="text-indent: 24pt"> 下面定义Length与数值的乘法重载运算符，它包括了<u>数值*长度</u>和<u>长度*数值</u>两种情况。这也是二元操作的一个例子</p><pre>value <span style="color: #0000ff">class</span> Length
{
	<span style="color: #008000">//...</span>

	<span style="color: #0000ff">static</span> Length <span style="color: #0000ff">operator</span>*(<span style="color: #0000ff">double</span> x, Length len);
	<span style="color: #0000ff">static</span> Length <span style="color: #0000ff">operator</span>*(Length len, <span style="color: #0000ff">double</span> x);
};</pre>
<p style="text-indent: 24pt">&nbsp;&nbsp; 函数的定义如下</p><pre>Length Length::<span style="color: #0000ff">operator</span>*(<span style="color: #0000ff">double</span> x, Length len)
{
	<span style="color: #0000ff">int</span> ins = safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(x*len.inches + x*len.feet*inchesPerFoot);
	<span style="color: #0000ff">return</span> Length( ins/12, ins%12 );
}

length Length::<span style="color: #0000ff">operator</span>*(Length len, <span style="color: #0000ff">double</span> x)
{
	<span style="color: #0000ff">return</span> <span style="color: #0000ff">operator</span>*(x, len);
}</pre>
<p style="text-indent: 24pt"> 下面定义递增运算符，这是一个一元运算符，可用同一个函数来定义前缀递增和后缀递增运算，编译器能够自动的根据调用情况来判断是先递增还是后递增。</p><pre><span style="color: #0000ff">static</span> Length <span style="color: #0000ff">operator</span>++(Length len)
{
	++len.inches;
	len.feet += len.inches/len.inchesPerFoot;
	len.inches %= len.inchesPerFoot;
	<span style="color: #0000ff">return</span> len;
}</pre>
<h1> 二、引用类中重载运算符</h1>
<p style="text-indent: 24pt">在引用类中重载运算符的方法与数值类基本相同，主要区别是形参和返回值一般都是句柄。这里就不再赘述了。</p><img src ="http://www.cppblog.com/golq/aggbug/90790.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-22 00:30 <a href="http://www.cppblog.com/golq/archive/2009/07/22/90790.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(九):类的属性</title><link>http://www.cppblog.com/golq/archive/2009/07/20/90565.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Sun, 19 Jul 2009 16:52:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/20/90565.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/90565.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/20/90565.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/90565.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/90565.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt">属性是C++/CLI的类成员，它类似于成员变量，但实际上不是。其主要区别在于，字段名引用了某个存储单元，而属性名则是调用某个函数。属性拥有访问属性的set()和get()函数。当我们使用属性名时，实际上在调用该函数的get()或set()函数。如果一个属性仅提供了get()函数，则它是只读属性；如果一个属性仅提供set()函数，则它是只写属性。</p> <p style="text-indent: 24pt">类可以有2种不同的属性：标量属性和索引属性。标量属性是指通过属性名来访问的单值；索引属性是利用属性名加方框号来访问的一组值。如 String类，其Length属性为标量属性，用object-&gt;Length来访问其长度，且Length是个只读属性。String还包含了索引属性，可以用object[idx]来访问字符串中第idx+1个字符。</p> <p style="text-indent: 24pt">属性可以与类的实例（类对象）相关，此时属性被称为实例属性，如String类的Length属性；如果用static修饰符指定属性，则属性为类属性，所有该类得实例都具有相同的属性值。</p> <h1>一、标量属性</h1> <p style="text-indent: 24pt">标量属性是单值，用property关键字可定义标量属性，还需要定义其get()和set()函数，如下例所示</p><pre>value <span style="color: #0000ff">class</span> Height
{
<span style="color: #0000ff">private</span>:
	<span style="color: #008000">// Records the height in feet and inches</span>
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;
	literal <span style="color: #0000ff">int</span> inchesPerFoot = 12;
	literal <span style="color: #0000ff">double</span> inchesToMeter = 2.54/100;

<span style="color: #0000ff">public</span>:
	<span style="color: #008000">// Create a height from inches value</span>
	Height(<span style="color: #0000ff">int</span> ins)
	{
		feet = ins/inchesPerFoot;
		inches = ins%inchesPerFoot;
	}

	<span style="color: #008000">// Create a height from feet and inches</span>
	Height(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) : feet(ft), inches(ins) {};

	<span style="color: #008000">// The height in meters as a property</span>
	property <span style="color: #0000ff">double</span> meters
	{
		<span style="color: #0000ff">double</span> get()
		{
			<span style="color: #0000ff">return</span> inchesToMeters * (feet*inchesPerFoot + inches);
		}
	}

	<span style="color: #008000">// Create a string representation of the object</span>
	<span style="color: #0000ff">virtual</span> String^ ToString() overrides
	{
		<span style="color: #0000ff">return</span> feet + L"<span style="color: #8b0000"> feet </span>" + inches + L"<span style="color: #8b0000"> inches</span>";
	}
};</pre>
<p style="text-indent: 24pt">上面的例子定义了一个merters的属性，下面是属性的用法</p><pre>Height ht = Height(6, 8);
Console::WriteLine(L"<span style="color: #8b0000">The height is {0} meters</span>", ht-&gt;meters);</pre>
<p style="text-indent: 24pt">属性不一定要定义成内联函数，也可以在.cpp中外部定义它，如在上例的定义中仅保留get()函数声明</p><pre>	property <span style="color: #0000ff">double</span> meters
	{
		<span style="color: #0000ff">double</span> get();
	}</pre>
<p style="text-indent: 24pt">函数定义在.cpp中时，需要加类名和函数名的限定（但不需要返回值？），方法如下：</p><pre>Height::meters::get()
{
	<span style="color: #0000ff">return</span> inchesToMeters*(feet*inchesPerFoot+inches);
}</pre>
<p style="text-indent: 24pt">如果定义一个属性时，不提供get()和set()函数定义，这种属性被称为平凡标量属性。对于此类属性，编译器将提供一个默认的get()和set()实现，如下例所示：</p><pre>value <span style="color: #0000ff">class</span> Point
{
<span style="color: #0000ff">public</span>:
	property <span style="color: #0000ff">int</span> x;
	proterty <span style="color: #0000ff">int</span> y;

	<span style="color: #0000ff">virtual</span> String^ ToString() overrides
	{
		<span style="color: #0000ff">return</span> L"<span style="color: #8b0000">(</span>"+x+L"<span style="color: #8b0000">,</span>"+y+"<span style="color: #8b0000">)</span>";		<span style="color: #008000">// Result is (x,y)</span>
	}
};</pre>
<p style="text-indent: 24pt">下面是一个完整的例子，说明了标量属性的声明及其使用方法</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d4ee118f-fa7e-4785-8c18-0c804bebc2a6" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex7_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex7_16.cpp : main project file.</span>

#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #008000">// Class defining a person's height</span>
value <span style="color: #0000ff">class</span> Height
{
<span style="color: #0000ff">private</span>:
	<span style="color: #008000">// Record the height in feet and inches</span>
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;

	literal <span style="color: #0000ff">int</span> inchesPerFoot = 12;
	literal <span style="color: #0000ff">double</span> inchesToMeters = 2.54/100;

<span style="color: #0000ff">public</span>:
	<span style="color: #008000">// Create a height from inches value</span>
	Height(<span style="color: #0000ff">int</span> ins)
	{
		feet = ins/inchesPerFoot;
		inches = ins%inchesPerFoot;
	}

	<span style="color: #008000">// Create a height from feet and inches</span>
	Height(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) : feet(ft), inches(ins) {};

	<span style="color: #008000">// The height in meters</span>
	property <span style="color: #0000ff">double</span> meters
	{
		<span style="color: #0000ff">double</span> get()
		{
			<span style="color: #0000ff">return</span> inchesToMeters*(feet*inchesPerFoot+inches);
		}
	}

	<span style="color: #008000">// Create a string representation of the object</span>
	<span style="color: #0000ff">virtual</span> String^ ToString() override
	{
		<span style="color: #0000ff">return</span> feet + L"<span style="color: #8b0000"> feet </span>" + inches + L"<span style="color: #8b0000"> inches</span>";
	}
};

<span style="color: #008000">// Class defining a person's weight</span>
value <span style="color: #0000ff">class</span> Weight
{
<span style="color: #0000ff">private</span>:
	<span style="color: #0000ff">int</span> lbs;
	<span style="color: #0000ff">int</span> oz;

	literal <span style="color: #0000ff">int</span> ouncesPerPound = 16;
	literal <span style="color: #0000ff">double</span> lbsToKg = 1.0/2.2;

<span style="color: #0000ff">public</span>:
	Weight(<span style="color: #0000ff">int</span> pounds, <span style="color: #0000ff">int</span> ounces)
	{
		lbs = pounds;
		oz = ounces;
	}

	property <span style="color: #0000ff">int</span> pounds
	{
		<span style="color: #0000ff">int</span> get() { <span style="color: #0000ff">return</span> lbs; }
		<span style="color: #0000ff">void</span> set(<span style="color: #0000ff">int</span> value) { lbs = value; }
	}

	property <span style="color: #0000ff">int</span> ounces
	{
		<span style="color: #0000ff">int</span> get() { <span style="color: #0000ff">return</span> oz; }
		<span style="color: #0000ff">void</span> set(<span style="color: #0000ff">int</span> value) { oz = value; }
	}

	property <span style="color: #0000ff">double</span> kilograms
	{
		<span style="color: #0000ff">double</span> get() { <span style="color: #0000ff">return</span> lbsToKg*(lbs+oz/ouncesPerPound); }
	}

	<span style="color: #0000ff">virtual</span> String^ ToString() override
	{
		<span style="color: #0000ff">return</span> lbs + L"<span style="color: #8b0000"> pounds </span>" + oz + L"<span style="color: #8b0000"> ounces</span>";
	}
};

ref <span style="color: #0000ff">class</span> Person
{
<span style="color: #0000ff">private</span>:
	Height ht;
	Weight wt;

<span style="color: #0000ff">public</span>:
	property String^ Name;

	Person(String^ name, Height h, Weight w) : ht(h), wt(w)
	{
		Name = name;
	}

	Height getHeight() { <span style="color: #0000ff">return</span> ht; }
	Weight getWeight() { <span style="color: #0000ff">return</span> wt; }
};

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Weight hisWeight = Weight(185, 7);
	Height hisHeight = Height(6, 3);
	Person^ him = gcnew Person(L"<span style="color: #8b0000">Fred</span>", hisHeight, hisWeight);

	Weight herWeight = Weight(105, 3);
	Height herHeight = Height(5, 2);
	Person^ her = gcnew Person(L"<span style="color: #8b0000">Freda</span>", herHeight, herWeight);

	Console::WriteLine(L"<span style="color: #8b0000">She is {0}</span>", her-&gt;Name);
	Console::WriteLine(L"<span style="color: #8b0000">Her weight is {0:F2} kilograms.</span>", her-&gt;getWeight().kilograms);
	Console::WriteLine(L"<span style="color: #8b0000">Her height is {0} which is {1:F2} meters.</span>", her-&gt;getHeight(), 
		her-&gt;getHeight().meters);

	Console::WriteLine(L"<span style="color: #8b0000">He is {0}</span>", him-&gt;Name);
	Console::WriteLine(L"<span style="color: #8b0000">His weight is {0}</span>", him-&gt;getWeight());
	Console::WriteLine(L"<span style="color: #8b0000">His height is {0} which is {1:F2} meters.</span>", him-&gt;getHeight(), 
		him-&gt;getHeight().meters);

    <span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2fdda0db-8a46-49ba-b888-b5880b7e60a7" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex7_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre>输出为</pre><pre>She is Freda
Her weight is 47.73 kilograms.
Her height is 5 feet 2 inches which is 1.57 meters.
He is Fred
His weight is 185 pounds 7 ounces
His height is 6 feet 3 inches which is 1.91 meters.</pre>
<h1>二、索引属性</h1>
<p style="text-indent: 24pt"> 索引属性是类的一组属性值，其访问方法同数组元素那样，在方括号内加索引值来访问。如果在方括号前面的是类对象的名称，则该索引属性被称为默认索引属性（如String^ obj可以用obj[idx]来访问字符串中第idx+1个字符），如果用属性名[idx]来访问索引属性值，则称为有名索引属性。下面的代码在类Name中定义了一个默认索引属性，</p><pre>ref <span style="color: #0000ff">class</span> Name
{
<span style="color: #0000ff">private</span>:
	array&lt;String^&gt;^ Names;

<span style="color: #0000ff">public</span>:
	Name(...array&lt;String^&gt;^ names) : Names(names) {}
	
	<span style="color: #008000">// Indexed property to return any name</span>
	property String^ <span style="color: #0000ff">default</span>[<span style="color: #0000ff">int</span>]
	{
		<span style="color: #008000">// Retrieve indexed property value</span>
		String^ get(<span style="color: #0000ff">int</span> index)
		{
			<span style="color: #0000ff">if</span>(index &gt;= Names-&gt;Length)
				<span style="color: #0000ff">throw</span> gcnew Exception(L"<span style="color: #8b0000">Index out of range</span>");
			<span style="color: #0000ff">return</span> Names[index];
		}
	}
};</pre>
<p style="text-indent: 24pt"> 在上面的例子中，如果将default换成别的名字，则该属性就成为一个有名索引属性。在定义索引属性时，方括号内用int指定了索引的数据类型为int型，它也可以是别的数据类型。访问索引属性的get()函数的形参其数据类型必须与属性名后方括号内类型相同；set()函数必须有2个形参，第一个指定索引，第二个指定属性元素的值。</p>
<p style="text-indent: 24pt">下面是一个完整的例子，说明了索引属性的定义与使用方法。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:9176079d-ef7c-4884-a1c3-78cbf1ba8852" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex7_17.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex7_17.cpp : main project file.</span>

#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

ref <span style="color: #0000ff">class</span> Name
{
<span style="color: #0000ff">private</span>:
	array&lt;String ^&gt;^ Names;

<span style="color: #0000ff">public</span>:
	Name(...array&lt;String ^&gt;^ names) : Names(names) {}

	<span style="color: #008000">// Scalar property specifying number of names</span>
	property <span style="color: #0000ff">int</span> NameCount
	{
		<span style="color: #0000ff">int</span> get() { <span style="color: #0000ff">return</span> Names-&gt;Length; }
	}

	<span style="color: #008000">// Indexed property to return names</span>
	property String^ <span style="color: #0000ff">default</span>[<span style="color: #0000ff">int</span>]
	{
		String ^ get(<span style="color: #0000ff">int</span> index)
		{
			<span style="color: #0000ff">if</span>(index &gt;= Names-&gt;Length)
				<span style="color: #0000ff">throw</span> gcnew Exception(L"<span style="color: #8b0000">Index out of range</span>");
			<span style="color: #0000ff">return</span> Names[index];
		}
	}
};

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Name^ myName = gcnew Name(L"<span style="color: #8b0000">Ebenezer</span>", L"<span style="color: #8b0000">Isaiah</span>", L"<span style="color: #8b0000">Ezra</span>", L"<span style="color: #8b0000">Inigo</span>", L"<span style="color: #8b0000">Whelkwhistle</span>");

	<span style="color: #008000">// List the names</span>
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;myName-&gt;NameCount; i++)
		Console::WriteLine(L"<span style="color: #8b0000">Name {0} is {1}</span>", i+1, myName[i]);
    <span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:8d1b6c57-6cf6-498b-aa32-ff23b7644211" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex7_17.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre>输出为</pre><pre>Name 1 is Ebenezer
Name 2 is Isaiah
Name 3 is Ezra
Name 4 is Inigo
Name 5 is Whelkwhistle</pre>
<p style="text-indent: 24pt"> 索引属性的索引也可以不是整型，甚至可以不是数字，下面的例子定义了一个商店类，其属性Opening指定了商店的开门时间，访问该属性的索引有2个参数，如下面的例子所示</p><pre><span style="color: #0000ff">enum</span> <span style="color: #0000ff">class</span> Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };

<span style="color: #008000">// class defining a shop</span>
ref <span style="color: #0000ff">class</span> Shop
{
<span style="color: #0000ff">public</span>:
	property String^ Opening[Day, String^]	<span style="color: #008000">// Opening times</span>
	{
		String ^ get(Day day, String^ AmOrPm)
		{
			<span style="color: #0000ff">switch</span>(day)
			{
				<span style="color: #0000ff">case</span> Day::Saturday:
					<span style="color: #0000ff">if</span>(AmOrPm == L"<span style="color: #8b0000">am</span>")
						<span style="color: #0000ff">return</span> L"<span style="color: #8b0000">9:00</span>";
					<span style="color: #0000ff">else</span>
						<span style="color: #0000ff">return</span> L"<span style="color: #8b0000">14:30</span>";
					<span style="color: #0000ff">break</span>;

				<span style="color: #0000ff">case</span> Day::Sunday:
					<span style="color: #0000ff">return</span> L"<span style="color: #8b0000">closed</span>";
					<span style="color: #0000ff">break</span>;

				<span style="color: #0000ff">default</span>:
					<span style="color: #0000ff">if</span>(AmOrPm == L"<span style="color: #8b0000">am</span>")
						<span style="color: #0000ff">return</span> L"<span style="color: #8b0000">9:30</span>";
					<span style="color: #0000ff">else</span>
						<span style="color: #0000ff">return</span> L"<span style="color: #8b0000">14:00</span>";
					<span style="color: #0000ff">break</span>;
			}
		}
	}
};</pre><pre>使用该类的方法如下</pre><pre>Shop^ shop = gcnew Shop;
Console::WriteLine(shop-&gt;Opening(Day::Saturday, L"<span style="color: #8b0000">pm</span>");</pre>
<h1>三、静态属性</h1>
<p style="text-indent: 24pt"> 静态属性为类的所有实例共有，类似于类的静态成员变量。通过在属性定义前添加修饰符static来定义，如下面的例子所示</p><pre>value <span style="color: #0000ff">class</span> Length
{
<span style="color: #0000ff">public</span>:
	<span style="color: #0000ff">static</span> property String ^ Units
	{
		String ^ get() { <span style="color: #0000ff">return</span> L"<span style="color: #8b0000">feet and inches</span>"; }
	}
};</pre>
<p style="text-indent: 24pt"> 无论是否创建类实例，静态属性都存在。如果已经定义了类实例，则可以用实例名.属性名来访问静态属性。对于上面的例子如果已经定义了一个类对象len，则可以如此访问其静态属性：</p><pre>Console::WriteLine(L"<span style="color: #8b0000">Class units are {0}.</span>", len.Units);</pre>
<p style="text-indent: 24pt">&nbsp;<font color="#ffff80"><strong>注意：在定义了属性之后，对应的get_属性名和set_属性名自动成为系统保留名称，不能为其它目的而使用他们。如果定义了默认索引属性，则set_Item和get_Item也成为系统保留名称，不可被使用。</strong></font></p><img src ="http://www.cppblog.com/golq/aggbug/90565.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-20 00:52 <a href="http://www.cppblog.com/golq/archive/2009/07/20/90565.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(八):类的分类与定义</title><link>http://www.cppblog.com/golq/archive/2009/07/12/89875.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Sun, 12 Jul 2009 08:45:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/12/89875.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/89875.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/12/89875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/89875.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/89875.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt">C++/CLI中可以定义两种类型的struct和class类型，一种为数值类（或数值结构）：value class(value struct)；一种是引用类（或引用结构）：ref class(ref value)。与本地C++一样，class与struct的区别在于前者的成员默认为私有，后者默认为公有。下面仅以类来介绍，内容同样适用于结构。</p> <p style="text-indent: 24pt">value class与ref class组成的是双关键字，也就是说，单独的value、ref并不是关键字。数值类与引用类的区别，以及它们与本地C++类的区别主要包括以下几个方面：</p> <ul> <li> <div style="text-indent: 24pt">数值类的对象包含自己的数据，<font color="#ffff00"><strong>引用类的对象只能用句柄来访问</strong></font>。</div> <li> <div style="text-indent: 24pt">在C++/CLI中，函数成员不能声明为const类型，取而代之的是字面值类型，修饰词关键字为 literal。</div> <li> <div style="text-indent: 24pt">在非静态函数成员中，this指针类型与本地C++不同：数值类的this指针为内部指针类型(interior_ptr&lt;T&gt;)，而引用类的this指针为句柄类型(T^)。</div> <li> <div style="text-indent: 24pt">C++/CLI类的数据成员不能包含本地C++数组或本地C++类对象。</div> <li> <div style="text-indent: 24pt">C++/CLI类无友元函数。</div> <li> <div style="text-indent: 24pt">C++/CLI类的数据成员不能包含<strong>位类型</strong>的数据成员。（什么是位数据类型）</div> <li> <div style="text-indent: 24pt">C++/CLI类的函数成员不能有默认的形参。</div></li></ul> <p style="text-indent: 24pt">此外，在C++/CLI中，不推荐类命名时使用前缀‘C’，其成员变量命名也不用前缀’m_’。</p> <h1>一、定义数值类</h1> <p style="text-indent: 24pt">数值类主要用于表示具有有限个数据成员的简单对象，其定义方法与本地C++类基本相同。首先看一个定义数值类，以及使用类的完整例子。</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7cf3a455-eb5c-4162-8a9e-afdc551c626a" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex7_14.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex7_14.cpp : main project file.</span>

#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #008000">// class representing a height</span>
value <span style="color: #0000ff">class</span> Height
{
<span style="color: #0000ff">private</span>:
	<span style="color: #008000">// Records the height in feet and inches</span>
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;

<span style="color: #0000ff">public</span>:
	<span style="color: #008000">// Create a height from inches value</span>
	Height(<span style="color: #0000ff">int</span> ins)
	{
		feet = ins/12;
		inches = ins%12;
	}

	<span style="color: #008000">// Create a height fromm feet and inches</span>
	Height(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) : feet(ft), inches(ins) {}
};

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Height myHeight = Height(6, 3);
	Height^ yourHeight = Height(70);
	Height hisHeight = *yourHeight;

	Console::WriteLine(L"<span style="color: #8b0000">My height is {0}</span>", myHeight);
	Console::WriteLine(L"<span style="color: #8b0000">Your height is {0}</span>", yourHeight);
	Console::WriteLine(L"<span style="color: #8b0000">His height is {0}</span>", hisHeight);
    <span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1d1cbf1c-5f83-4c1f-9c32-524e015fe122" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex7_14.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt">输出为</p><pre>My height is <font color="#ffff00">Height</font>
Your height is <font color="#ffff00">Height</font>
His height is <font color="#ffff00">Height</font></pre>
<p style="text-indent: 24pt">在上面的例子中，myHeight和hisHeight被分配在堆栈上，yourHeight被分配到了CLR堆上。其中hisHeight是yourHeight的一个副本，当向 hisHeight赋值时，需要用*操作符对句柄yourHeight进行解除引用计算。这是因为<strong>数值类对象总是包含自己的数据</strong>，因此它们不能引用同一个对象，在赋值时总是采用复制的方式进行。注意：<font color="#ffff00"><strong>在C++/CLI中，不能重写默认构造函数。默认构造函数将所有的值类型数据成员初始化为0，将引用类型（句柄）初始化为nullptr。同样，也不能重载复制构造函数和赋值操作符。默认的复制操作是将每一个数据成员进行复制，对象间的赋值也是如此</strong></font>。</p>
<p style="text-indent: 24pt">C++/CLI中的类都有一个成员函数ToString()，它返回一个表示对象的字符串句柄。默认情况下，该字符串为类名。这从上面的输出可以看出：传递给WriteLine()函数的是Height对象，结果输出的并非对象所包含的高度值，而是类名Height，这是因为编译器认为此处需要调用该对象的字符串表示法，因此安排的ToString()函数调用，这个过程可以显示的表达为</p><pre><span style="color: #0000ff">double</span> pi = 3.142;
Console::WriteLine(pi.ToString());</pre>
<p style="text-indent: 24pt">double类型被映射到System命名空间中的System::Double类，该类实现了ToString方法，因此可以正确的输出变量pi的数值3.142而非类名Double。在上面的例子中，为了正确地输出高度，可给Height定义中增加ToString()的重载函数。</p><pre>	<span style="color: #008000">//Create a string repesentation og the object</span>
	<span style="color: #0000ff">virtual</span> String^ ToString() override
	{
		<span style="color: #0000ff">return</span> feet + L"<span style="color: #8b0000"> feet </span>" + inches + L"<span style="color: #8b0000"> inches</span>";
	}</pre>
<p style="text-indent: 24pt">现在可以正确的输出为</p><pre>My height is 6 feet 3 inches
Your height is 5 feet 10 inches
His height is 5 feet 10 inches</pre>
<p style="text-indent: 24pt">在定义数值类时，如果数据成员为常量，C++/CLI中将其定义为”字面值”(literial)。在上面的例子中，将12定义为字面值，可以使得代码的可读性更高，避免“幻数”的出现（意指程序代码中难以理解其来源或意义的常数，如上面例子中的12）。定义字面值的方法如下</p><pre>value <span style="color: #0000ff">class</span> Height
{
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;
	literial <span style="color: #0000ff">int</span> inchesPerFoot = 12;
	
	<span style="color: #008000">// Other code...</span>
};</pre>
<p style="text-indent: 24pt">这样就可以在其后直接使用该字面值，而非难以理解的12了</p><pre>Height(<span style="color: #0000ff">int</span> ins)
{
	feet = ins/ inchesPerFoot;
	inches = ins% inchesPerFoot;
}</pre>
<p style="text-indent: 24pt">利用”字面值”leterial来定义常量的一个缺点是：必须在定义常量的同时指定它的值。另外一种定义常量的方法是使用initonly修饰符，使用该修饰符的常量变量只能在构造函数的初始化表，或者构造函数体内进行一次初始化， 之后再也不能被修改。注意：<strong><font color="#ffff00">不能在声明非静态initonly常量时指定初值，而必须是在构造函数的初始化表或构造函数体内。</font></strong>下面的例子描述了onlyinit的用法</p><pre>value <span style="color: #0000ff">class</span> Length
{
<span style="color: #0000ff">private</span>:
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;
	
<span style="color: #0000ff">public</span>:
	initonly <span style="color: #0000ff">int</span> inchesPerFoot;
	
	<span style="color: #008000">// Constructor</span>
	Length(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) : 
		feet(ft), inches(ins),
		inchesPerFoot(12);
}</pre><pre>上面的构造函数也可以写成</pre><pre>Lenght(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) :
	feet(ft), inches(ins)
{
	inchesPerFoot = 12;
}</pre>
<p style="text-indent: 24pt"> 如果是静态地initonly变量，则只能在定义时指定初值。因为如果自构造函数中定义，则每次创建类实例都将对静态变量赋值，这显然与静态、常量这样的概念冲突。解决的办法是，如果一定要在构造函数中初始化initonly类型的静态常量，则可定义一个静态构造函数。</p><pre>value <span style="color: #0000ff">class</span> Length
{
<span style="color: #0000ff">private</span>:
	<span style="color: #0000ff">int</span> feet;
	<span style="color: #0000ff">int</span> inches;

	<span style="color: #0000ff">static</span> Length() { inchesPerFoot = 12; }

<span style="color: #0000ff">public</span>:
	initonly <span style="color: #0000ff">static</span> <span style="color: #0000ff">int</span> inchesPerFoot;

	Length(<span style="color: #0000ff">int</span> ft, <span style="color: #0000ff">int</span> ins) :
		feet(ft), inches(ins)
	{ }
};</pre>
<p style="text-indent: 24pt"><font color="#ffff00"><strong>静态构造函数函数没有形参，且没有初始化表，总是被声明为private。它不能被直接调用，而是由普通构造函数在调用之前自动调用。</strong></font>这种方法与在定义静态initonly变量时指定初始值的唯一区别是，初始化值可以是在运行时确定的。</p>
<h1>二、定义引用类</h1>
<p style="text-indent: 24pt">引用类更加类似于本地C++类，它没有数值类那么多的限制。但引用类没有默认的复制构造函数和赋值运算符，如果定义的类需要进行复制或赋值，必须显式地添加相应的函数成员。下面的例子定义了一个引用类及其使用方法。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:bd0d1089-3e48-4aca-8133-49dbbcdc4557" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex7_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p></p><pre><span style="color: #008000">// Ex7_15.cpp : main project file.</span>

#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

ref <span style="color: #0000ff">class</span> Box
{
<span style="color: #0000ff">public</span>:
	<span style="color: #008000">// No-arg constructor supplying default field values</span>
	Box():Length(1.0), Width(1.0), Height(1.0)
	{
		Console::WriteLine(L"<span style="color: #8b0000">No-arg constructot called.</span>");
	}
	<span style="color: #008000">// Constructor definition using an initialisation list</span>
	Box(<span style="color: #0000ff">double</span> lv, <span style="color: #0000ff">double</span> bv, <span style="color: #0000ff">double</span> hv):Length(lv), Width(bv), Height(hv)
	{
		Console::WriteLine(L"<span style="color: #8b0000">Constructor called.</span>");
	}

	<span style="color: #008000">// Function to calculate the volume of a box</span>
	<span style="color: #0000ff">double</span> Volume()
	{
		<span style="color: #0000ff">return</span> Length*Width*Height;
	}

<span style="color: #0000ff">private</span>:
	<span style="color: #0000ff">double</span> Length;
	<span style="color: #0000ff">double</span> Width;
	<span style="color: #0000ff">double</span> Height;
};

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Box^ aBox;
	Box^ newBox = gcnew Box(10, 15, 20);
	aBox = gcnew Box;

	Console::WriteLine(L"<span style="color: #8b0000">Default box volume is {0}</span>", aBox-&gt;Volume());
	Console::WriteLine(L"<span style="color: #8b0000">New box volume is {0}</span>", newBox-&gt;Volume());
    <span style="color: #0000ff">return</span> 0;
}</pre>
<p></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3b6557d7-b6ae-4fad-83f5-19286ddbb808" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex7_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p></p>
<p>输出为</p><pre>Constructor called.
No-arg constructot called.
Default box volume is 1
New box volume is 3000</pre>
<p style="text-indent: 24pt">在上面的例子中，main()函数的第一句没有创建任何对象，仅仅声明了一个句柄，并被默认的赋值成nullptr。此外，引用对象总是在堆上创建，因此总是用gcnew来调用其构造函数，并用句柄来跟踪引用对象。</p><img src ="http://www.cppblog.com/golq/aggbug/89875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-12 16:45 <a href="http://www.cppblog.com/golq/archive/2009/07/12/89875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(七):类函数</title><link>http://www.cppblog.com/golq/archive/2009/07/10/89699.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Thu, 09 Jul 2009 16:21:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/10/89699.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/89699.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/10/89699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/89699.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/89699.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt"> 类函数是C++/CLI中引入的新概念，其功能类似于函数模板，但原理上却迥然不同。使用函数模板时，编译器根据模板生成函数源代码，然后将其与其它代码一起编译。这种方法可能会产生许多函数，从而使得生成模块的体积增加，这就是所谓的“代码膨胀”。类函数与之不同，类函数本身将被编译，在调用类函数时，实际类型在运行时取代了类函数的类型形参，这不会导致新增代码的问题。</p> <h1>一、类函数的定义</h1> <p style="text-indent: 24pt">类函数与普通函数的区别在于：它需要定义一个特殊的形参——类型形参，该参数说明在运行时传递给函数的参数类型。下面的例子定义了一个类函数，用于找出某种数据类型数组中最大的元素。</p><pre>generic&lt;<span style="color: #0000ff">typename</span> T&gt; where T:IComparable
T MaxElement(array&lt;T&gt;^ x)
{
	T max = x[0];
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=1; i&lt;x-&gt;Lenght; i++)
		<span style="color: #0000ff">if</span>(max-&gt;CompareTo(x[i])&lt;0)
			max = x[i];
	<span style="color: #0000ff">return</span> max;
}</pre>
<p style="text-indent: 24pt"> 关键字generic规定后面的内容为类函数定义，尖括号内用关键字typename定义了一个类型形参T，如果有多个类型形参，它们都放在尖括号内，用逗号分开。</p>
<p style="text-indent: 24pt">关键字where引入使用类函数时，传递给T的类型实参应满足的约束条件。这里的条件是：所有用于替代T的类型必须实现了IComparable接口。该约束也意味着，所有传入的类型实参都实现了CompareTo()函数，允许对该类型两个对象进行比较。</p>
<p style="text-indent: 24pt">第二行定义了函数的返回值类型、函数名称以及形参，与普通函数定义类似，但有的类型用T来描述，它们将在运行时被确定。</p>
<h1>二、使用类函数</h1>
<p style="text-indent: 24pt">调用类函数的方法与调用普通函数的方法一样。对上面声明的MaxElement()函数可如此调用：</p><pre>array&lt;<span style="color: #0000ff">double</span>&gt;^ data = {1.5, 3.5, 6.7, 4.2, 2.1};
<span style="color: #0000ff">double</span> maxData = MaxElement(data);</pre>
<p style="text-indent: 24pt">&nbsp;<font face="Courier New">在这个例子中，编译器能够判断出该类函数的类型实参为double，生成调用函数的代码(并非是该类函数的double版)，执行时再用 double代替T。注意：与函数模板不同，对于类函数编译器不创建函数实例，而是仅仅是使编译后的代码可以接受数据类型作为类型实参，实际的类型替换在运行时实现。</font></p>
<p style="text-indent: 24pt"><font face="Courier New">应该注意的是，如果以字符串常量作为实参传递给类函数，编译器将认为类型实参是String^，无论该字符串常量是窄字符串(“Hello”)还是宽字符串(L“Hello”)。</font></p>
<p style="text-indent: 24pt"><font face="Courier New">有些情况下，编译器无法根据函数调用来判断类型实参是什么，这时可用在函数名后面加尖括号和类型名称来显示的指定，上面的例子也可以写作</font></p><pre><span style="color: #0000ff">double</span> maxData = MaxElement&lt;<span style="color: #0000ff">double</span>&gt;(data);</pre>
<p style="text-indent: 24pt"> 另外需要注意的是，提供给类函数作为类型实参的不能是本地C++<strong><font color="#ffff00">类</font></strong>类型、本地指针、引用，也不能是值类类型的句柄(如 int^)。而只能是值类型(如int、double)或引用类型的跟踪句柄(如String^)。</p>
<p style="text-indent: 24pt">下面是一个使用类函数的完整示例。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a5470f01-d78b-45ed-bd43-c793fa9b90a4" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex6_10.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex6_10.cpp : main project file.</span>
<span style="color: #008000">// Defining and using generic fuctions</span>
#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #008000">// Generic function to find the maximum element in an array</span>
generic&lt;<span style="color: #0000ff">typename</span> T&gt; where T:IComparable
T MaxElement(array&lt;T&gt;^ x)
{
	T max = x[0];
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=1; i&lt;x-&gt;Length; i++)
		<span style="color: #0000ff">if</span>(max-&gt;CompareTo(x[i])&lt;0)
			max = x[i];
	<span style="color: #0000ff">return</span> max;
}

<span style="color: #008000">// Generic function to remove an element from an array</span>
generic&lt;<span style="color: #0000ff">typename</span> T&gt; where T:IComparable
array&lt;T&gt;^ RemoveElement(T element, array&lt;T&gt;^ data)
{
	array&lt;T&gt;^ newData = gcnew array&lt;T&gt;(data-&gt;Length-1);
	<span style="color: #0000ff">int</span> Index = 0;		<span style="color: #008000">// Index to elements in newData array</span>
	<span style="color: #0000ff">bool</span> found = <span style="color: #0000ff">false</span>;	<span style="color: #008000">// Indicates that the element to remove from was found</span>
	<span style="color: #0000ff">for</span> each(T item in data)
	{
		<span style="color: #008000">// Check for invalid index or element found</span>
		<span style="color: #0000ff">if</span>((!found) &amp;&amp; item-&gt;CompareTo(element)==0 )
		{ 
			found = <span style="color: #0000ff">true</span>;
			<span style="color: #0000ff">continue</span>;
		}
		<span style="color: #0000ff">else</span>
		{
			<span style="color: #0000ff">if</span>(Index == newData-&gt;Length)
			{
				Console::WriteLine(L"<span style="color: #8b0000">Element to remove not found</span>");
				<span style="color: #0000ff">return</span> data;
			}
			newData[Index++] = item;
		}
	}
	<span style="color: #0000ff">return</span> newData;
}

<span style="color: #008000">// Generic function to list an array</span>
generic&lt;<span style="color: #0000ff">typename</span> T&gt; where T:IComparable
<span style="color: #0000ff">void</span> ListElements(array&lt;T&gt;^ data)
{
	<span style="color: #0000ff">for</span> each(T item in data)
		Console::Write(L"<span style="color: #8b0000">{0, 10}</span>", item);
	Console::WriteLine();
}

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;<span style="color: #0000ff">double</span>&gt;^ data = {1.5, 3.5, 6.7, 4.2, 2.1};
	Console::WriteLine(L"<span style="color: #8b0000">Array contains:</span>");
	ListElements(data);
	Console::WriteLine(L"<span style="color: #8b0000">\nMaximun element = {0}\n</span>", MaxElement(data));
	array&lt;<span style="color: #0000ff">double</span>&gt;^ result = RemoveElement(MaxElement(data), data);
	Console::WriteLine(L"<span style="color: #8b0000">After removing maximun, array contains:</span>");
	ListElements(result);


	array&lt;<span style="color: #0000ff">int</span>&gt;^ numbers = {3, 12, 7, 0, 10, 11};
	Console::WriteLine(L"<span style="color: #8b0000">Array contains:</span>");
	ListElements(numbers);
	Console::WriteLine(L"<span style="color: #8b0000">\nMaximun element = {0}\n</span>", MaxElement(numbers));
	Console::WriteLine(L"<span style="color: #8b0000">After removing maximun, array contains:</span>");
	ListElements(RemoveElement(MaxElement(numbers), numbers));

	array&lt;String^&gt;^ strings = {L"<span style="color: #8b0000">Many</span>", L"<span style="color: #8b0000">hands</span>", L"<span style="color: #8b0000">make</span>", L"<span style="color: #8b0000">light</span>", L"<span style="color: #8b0000">work</span>"};
	Console::WriteLine(L"<span style="color: #8b0000">Array contains:</span>");
	ListElements(strings);
	Console::WriteLine(L"<span style="color: #8b0000">\nMaximun element = {0}\n</span>", MaxElement(strings));
	Console::WriteLine(L"<span style="color: #8b0000">After removing maximun, array contains:</span>");
	ListElements(RemoveElement(MaxElement(strings), strings));

	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3c2ee93a-2a67-447a-a3f5-2e0786c9e984" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex6_10.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p>输出如下</p><pre>Array contains:
       1.5       3.5       6.7       4.2       2.1

Maximun element = 6.7

After removing maximun, array contains:
       1.5       3.5       4.2       2.1
Array contains:
         3        12         7         0        10        11

Maximun element = 12

After removing maximun, array contains:
         3         7         0        10        11
Array contains:
      Many     hands      make     light      work

Maximun element = work

After removing maximun, array contains:
      Many     hands      make     light</pre><img src ="http://www.cppblog.com/golq/aggbug/89699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-10 00:21 <a href="http://www.cppblog.com/golq/archive/2009/07/10/89699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(六):函数</title><link>http://www.cppblog.com/golq/archive/2009/07/09/89692.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Thu, 09 Jul 2009 14:33:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/09/89692.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/89692.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/09/89692.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/89692.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/89692.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt"> C++/CLI中函数的工作方式与ISO/ANSI C++完全相同，但由于在C++/CLI中用跟踪句柄和跟踪引用替代了本地指针和引用，因此也带来一些变化，主要包括</p> <ul> <li> <div style="text-indent: 24pt">CLR程序中函数的形参与返回值可以是数值类型、跟踪句柄、跟踪引用和内部指针。</div></li> <li> <div style="text-indent: 24pt">如果某个形参是CLR数组，程序不需要另外的参数指定其大小，因为数组大小在属性Length中。</div></li> <li> <div style="text-indent: 24pt">在C++/CLI程序中，不能像C++一样进行地址的算术运算，而应使用数组索引。（<font color="#80ffff">内部指针不是可以算术操作吗？</font>）</div></li> <li> <div style="text-indent: 24pt">可以方便的返回CLR堆上的句柄，因为CLR有垃圾回收机制自动清理无用的内存。</div></li> <li> <div style="text-indent: 24pt">C++/CLI函数接收可变长度参数的机制与本地C++不同。</div></li> <li> <div style="text-indent: 24pt">C++/CLI中main()函数访问命令行实参的机制与本地C++不同。</div></li></ul> <p style="text-indent: 24pt">下面就最后2条进行说明。</p> <h1>一、接收可变长度参数的函数</h1> <p style="text-indent: 24pt">C++/CLI允许将形参列表指定为数组，数组声明前面加省略号，从而实现实参的长度可变。</p><pre><span style="color: #0000ff">int</span> sum(...array&lt;<span style="color: #0000ff">int</span>&gt;^ args)
{
	<span style="color: #008000">// Code for sum</span>
}</pre>
<p style="text-indent: 24pt"> 上面的sum()函数可以接收任意数量的整数作为实参，在函数内部，通过访问数组args的元素就可以实现对实参的处理，实参个数由args的属性Length得到。下面是一个完整的例子，描述了该机制的工作过程。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:70406c10-895a-4b1c-8352-57db3ed7c7fc" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex5_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex5_15.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">double</span> sum(...array&lt;<span style="color: #0000ff">double</span>&gt;^ args)
{
	<span style="color: #0000ff">double</span> sum = 0.0;
	<span style="color: #0000ff">for</span> each(<span style="color: #0000ff">double</span> arg in args)
		sum += arg;
	<span style="color: #0000ff">return</span> sum;
}

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Console::WriteLine( sum(2.0, 4.0, 6.0, 8.0, 10.0, 12.0) );
	Console::WriteLine( sum(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9) );
        <span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1e8f354e-a53f-4669-82de-4cc9a8fa3f3b" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex5_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p>输出为</p><pre>42
49.5</pre>
<h1>二、main()的实参</h1>
<p style="text-indent: 24pt"> 从前面的例子可以看出，CLR程序中main()函数仅有一个形参，它为String^类型的数组，这就将处理命令行实参简化为访问该数组的元素。下面的例子展示了这个用法。</p>
<p style="text-indent: 24pt"> 此外还应注意：<font color="#ffff00">与本地C++中main()不同，命令行参数中不包括程序名称本身。</font></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d8d3f8e3-936b-41bb-b0e8-dc269718c70d" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex5_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex5_16.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Console::WriteLine(L"<span style="color: #8b0000">There were {0} command line arguments.</span>", args-&gt;Length);
	Console::WriteLine(L"<span style="color: #8b0000">Command line arguments received are:</span>");
	<span style="color: #0000ff">int</span> i=1;
	<span style="color: #0000ff">for</span> each(String^ str in args)
		Console::WriteLine(L"<span style="color: #8b0000">Argument {0}: {1}</span>", i++, str);
    
	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a510c156-52e4-4525-ba41-87a9f13257a6" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex5_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre>输出为</pre><pre>D:\My Documents\My Projects\Ex5_16\Debug&gt;ex5_16 tring multiple "<span style="color: #8b0000">arguments values</span>
"<span style="color: #8b0000"> 4.5 0.0</span>
There were 5 command line arguments.
Command line arguments received are:
Argument 1: tring
Argument 2: multiple
Argument 3: arguments values
Argument 4: 4.5
Argument 5: 0.0</pre><img src ="http://www.cppblog.com/golq/aggbug/89692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-09 22:33 <a href="http://www.cppblog.com/golq/archive/2009/07/09/89692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(五):跟踪句柄、跟踪引用及内部指针</title><link>http://www.cppblog.com/golq/archive/2009/07/09/89682.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Thu, 09 Jul 2009 13:47:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/09/89682.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/89682.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/09/89682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/89682.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/89682.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt">与本地C++自己维护堆不同，C++/CLI中动态分配的内存是由CLR来维护的。当不需要堆时，CLR自动将其删除回收，同时CLR还能自动地压缩内存堆以避免产生不必要的内存碎片。这种机制能够避免<strong>内存泄露</strong>和<strong>内存碎片</strong>，被称为垃圾回收，而由CLR管理的这种堆被称为CLR堆。它由操作符gcnew创建。</p> <p style="text-indent: 24pt">由于垃圾回收机制会改变堆中对象的地址，因此不能在CLR堆中使用普通C++指针，因为如果指针指向的对象地址发生了变化，则指针将不再有效。为了能够安全地访问堆对象，CLR提供了跟踪句柄（类似于C++指针）和跟踪引用（类似于C++）引用。</p> <h1>一、跟踪句柄</h1> <p style="text-indent: 24pt">跟踪句柄类似于本地C++指针，但能够被CLR垃圾回收器自动更新以反映被跟踪对象的新地址。同时不允许对跟踪句柄进行地址的算术运算，也不能够进行强制类型转换。</p> <p style="text-indent: 24pt">凡是在CLR堆上创建的对象必须被跟踪句柄引用，这些对象包括：(1)用gcnew操作符显示创建在堆上的对象；(2)所有的引用数据类型（数值类型默认分配在堆栈上）。<strong><font color="#ffff00">注意：所有分配在堆上的对象都不能在全局范围内被创建。</font></strong></p> <p style="text-indent: 24pt">关于跟踪句柄的相关使用方法参见《<a href="http://www.cppblog.com/golq/archive/2009/06/29/88733.html">C++/CLI学习入门(三):数组</a>》</p> <h1>二、跟踪引用</h1> <p style="text-indent: 24pt">跟踪引用类似于本地C++引用，表示某对象的别名。可以给堆栈上的值对象、CLR堆上的跟踪句柄创建跟踪引用。跟踪引用本身总是在堆栈上创建的。如果垃圾回收移动了被引用的对象，则跟踪引用将被自动更新。</p> <p style="text-indent: 24pt">跟踪引用用%来定义，下面的例子创建了一个对堆栈上值对象的跟踪引用：</p><pre><span style="color: #0000ff">int</span> value = 10;
<span style="color: #0000ff">int</span>% trackValue = value;</pre>
<p style="text-indent: 24pt">stackValue为value变量的引用，可以用stackValue来访问value：</p><pre>trackValue *= 5;
Console::WriteLine(value);	<span style="color: #008000">// Result is 50</span></pre>
<h1>三、内部指针</h1>
<p style="text-indent: 24pt">C++/CLI还提供一种用关键字interior_ptr定义的内部指针，它允许进行地址的算术操作。必要时，该指针内存储的地址会由CLR垃圾回收自动更新。注意，内部指针总是函数的局部自动变量。</p>
<p style="text-indent: 24pt">下面的代码定义了一个内部指针，它含有某数组中第一个元素的地址：</p><pre>array&lt;<span style="color: #0000ff">double</span>&gt;^ data = {1.5, 3.5, 6.7, 4.2, 2.1};
interior_ptr&lt;<span style="color: #0000ff">double</span>&gt; pstart = %data[0];</pre>
<p style="text-indent: 24pt"> 必须给interio_ptr指定内部指针指向的对象类型。此外还应该给指针进行初始化，如果不提供初始值，系统将其默认初始化为nullptr。</p>
<p style="text-indent: 24pt">内部指针在指定类型时应注意：可以包含堆栈上值类型对象的地址，也可以包含指向CLR堆上某对象句柄的地址，还可以是本地类对象或本地指针，但<strong><font color="#ffff80">不能是CLR堆上整个对象的地址</font></strong>。也就是说，可以使用内部指针存储作为CLR堆上对象组成部分的数值类对象（如CLR数组元素）的地址，也可以存储System::String对象跟踪句柄的地址，但不能存储String对象本身的地址。</p><pre>interior_ptr&lt;String^&gt; pstr1;	<span style="color: #008000">// OK -- pointer to a handle</span>
interior_ptr&lt;String&gt;  pstr2;	<span style="color: #008000">// ERROR -- pointer to a String object</span></pre>
<p style="text-indent: 24pt"> 与本地C++指针一样，内部指针可以进行算术计算。可以通过递增或递减来改变其包含的地址，从而引用后面或前面的数据项；还可在内部指针上加上或减去某个整数；可以比较内部指针。下面的例子展示了内部指针的用法：</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:8d41a68b-b569-4f25-9e07-79c6b4bd0941" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_19.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_19.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;<span style="color: #0000ff">double</span>&gt;^ data = {1.5, 3.5, 6.7, 4.2, 2.1};
	interior_ptr&lt;<span style="color: #0000ff">double</span>&gt; pstart = &amp;data[0];
	interior_ptr&lt;<span style="color: #0000ff">double</span>&gt; pend = &amp;data[data-&gt;Length - 1];
	<span style="color: #0000ff">double</span> sum = 0;

	<span style="color: #0000ff">while</span>(pstart&lt;=pend)
		sum += *pstart++;

	Console::WriteLine(L"<span style="color: #8b0000">Total of data array elements = {0}\n</span>", sum);

	array&lt;String^&gt;^ strings = { L"<span style="color: #8b0000">Land ahoy!</span>",
		L"<span style="color: #8b0000">Splice the mainbrace!</span>",
		L"<span style="color: #8b0000">Shiver me timbers!</span>",
		L"<span style="color: #8b0000">Never throw into the wind!</span>"
	};

	<span style="color: #0000ff">for</span>(interior_ptr&lt;String^&gt; pstrings = &amp;strings[0]; pstrings-&amp;strings[0] &lt; strings-&gt;Length; ++pstrings)
		Console::WriteLine(*pstrings);

    <span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b5322bef-6fae-4d98-9223-ec51140918e9" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex4_19.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p>输出为</p><pre>Total of data array elements = 18

Land ahoy!
Splice the mainbrace!
Shiver me timbers!
Never <span style="color: #0000ff">throw</span> into the wind!</pre><img src ="http://www.cppblog.com/golq/aggbug/89682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-09 21:47 <a href="http://www.cppblog.com/golq/archive/2009/07/09/89682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(四):字符串</title><link>http://www.cppblog.com/golq/archive/2009/07/07/89505.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Tue, 07 Jul 2009 15:39:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/07/07/89505.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/89505.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/07/07/89505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/89505.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/89505.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt">C++/CLI字符串（Unicode字符组成的字符串）是指在System命名空间中定义的String类，即由System:Char类型的字符序列组成的字符串。它包含大量强大的功能，使得字符串的处理非常容易。创建一个String对象的方法如下例所示：</p><pre>System::String^ saying = L"<span style="color: #8b0000">Many hands make light work.</span>";</pre>
<p style="text-indent: 24pt">跟踪句柄saying用于访问String类对象。该对象的字符为宽字符，因为采用了前缀 “L”，如果省略“L”，该字符串由8位的字符组成，编译器将确保将其转换成宽字符。</p>
<p style="text-indent: 24pt">访问字符串内字符可以像访问数组元素一样，使用索引来访问，首字符的索引为0。这种方法只能用于读取字符串内字符，但不能用于修改字符串的内容。</p><pre>Console::WriteLine("<span style="color: #8b0000">The third character in the string is {0}</span>", saying[2]);</pre>
<p style="text-indent: 24pt">利用Length属性，可以获取字符串内字符的数量（长度）。</p><pre>Console::WriteLine("<span style="color: #8b0000">The saying has {0} charactors.</span>", saying-&gt;Length);</pre>
<h1>一、连接字符串</h1>
<p style="text-indent: 24pt">利用 “+”可以连接字符串，形成新的字符串。执行下面的例子之后，name3将包含字符串 “Beth and Betty”。</p><pre>String^ name1 = L"<span style="color: #8b0000">Beth</span>";
String^ name2 = L"<span style="color: #8b0000">Betty</span>";
String^ name3 = name1+L"<span style="color: #8b0000"> and </span>"+name2;</pre>
<p style="text-indent: 24pt">“+”还可以用来连接字符串与数值、bool值等非字符串变量，在连接之前，这些变量将自动的转换成字符串。</p><pre>String^ str = L"<span style="color: #8b0000">Value: </span>";
String^ str1 = str + 2.5;	<span style="color: #008000">// str1 is "Value: 2.5"</span>
String^ str2 = str + 25;	<span style="color: #008000">// str2 is "Value: 25"</span>
String^ str3 = str + <span style="color: #0000ff">true</span>;	<span style="color: #008000">// str3 is "Value: True"</span></pre>
<p style="text-indent: 24pt">“+”还可以用来连接字符串与字符，但要注意，<strong>结果字符串的形式取决于字符的类型。</strong>这是因为char类型的字符被视为数值，wchar_t与String对象的字符具有相同的类型（Char类型）。</p><pre><span style="color: #0000ff">char</span> ch = 'Z';
wchar_t wch = 'Z';
String^ str4 = str + ch;	<span style="color: #008000">// str4 is "Value: 90"</span>
String^ str5 = str + wch;	<span style="color: #008000">// str5 is "Value: Z"</span></pre>
<p style="text-indent: 24pt">String类型定义了Join()函数，用于将数组中的多个字符串连接成一个字符串，数组元素之间用分隔符隔开，如</p><pre>array&lt;String^&gt;^ names = {"<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Mary</span>", "<span style="color: #8b0000">Eve</span>", "<span style="color: #8b0000">Bill</span>"};
String^ seperator = "<span style="color: #8b0000"> and </span>";
String^ joined = String::Join(seperator, names);	<span style="color: #008000">// joined is "Jill and Ted and Mary and Eve and Bill"</span></pre>
<p style="text-indent: 24pt"><strong>特别注意：String对象是固定不变的，一旦创建完毕后就不能再被修改了。这意味着所有的字符串操作都是在创建新的字符串。</strong></p>
<p style="text-indent: 24pt">下面的例子将整数数组内的元素按列整齐地输出。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:332fa510-2da2-4c81-9825-3ceed863ae66" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_17.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_17.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;<span style="color: #0000ff">int</span>&gt;^ values = { 2, 456, 23, -46, 34211, 456, 5609, 112098, 234,
		-76504, 341, 6788, -909121, 99, 10 };
	String^ formatStr1 = "<span style="color: #8b0000">{0, </span>";
	String^ formatStr2 = "<span style="color: #8b0000">}</span>";
	String^ number;

	<span style="color: #0000ff">int</span> maxLength = 0;
	<span style="color: #0000ff">for</span> each(<span style="color: #0000ff">int</span> value in values)
	{
		number = "<span style="color: #8b0000"></span>"+value;
		<span style="color: #0000ff">if</span>(maxLength&lt;number-&gt;Length)
			maxLength = number-&gt;Length;
	}

	String^ format = formatStr1+(maxLength+1)+formatStr2;

	<span style="color: #0000ff">int</span> numberPerLine = 3;
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;values-&gt;Length; i++)
	{
		Console::Write(format, values[i]);
		<span style="color: #0000ff">if</span>((i+1)%numberPerLine == 0)
			Console::WriteLine();
	}
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:39eaa58f-a5cc-4e1c-8310-d9c2137a5022" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex4_17.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt">输出为</p><pre>       2     456      23
     -46   34211     456
    5609  112098     234
  -76504     341    6788
 -909121      99      10</pre>
<h1>二、修改字符串</h1>
<p style="text-indent: 24pt">Trim()函数用于删除字符串头部和尾部的空格。不带参数调用该函数将删除字符串头、尾部的全部空格并返回一新字符串。</p><pre>String^ str = {"<span style="color: #8b0000"> Handsome is as handsome does...     </span>"};
String^ newStr = str-&gt;Trim();</pre>
<p style="text-indent: 24pt">也可传递给Trim()函数字符数组作为参数，字符串将<strong>从头部和尾部开始</strong>删除数组中的字符。如果字符出现在字符串中间，则不会被删除。</p><pre>String^ toBeTrimed = L"<span style="color: #8b0000">wool wool sheep sheep wool wool wool</span>";
array&lt;wchar_t&gt;^ notWanted = {L'w', L'o', L'l', L' ' };
Console::WriteLine(toBeTrimed-&gt;Trim(notWanted));</pre>
<p style="text-indent: 24pt">上面的语句将输出<br>sheep sheep</p>
<p style="text-indent: 24pt">如果在上面的语句中没有加前缀”L“，则字符为char类型，对应于System::SByte类型。不过编译器将自动地将其转换成wchar_t类型（即System::Char类型）。</p>
<p style="text-indent: 24pt">Trim()函数也支持直接输入要删除的字符列表，下面的语句将产生同样的输出</p><pre>Console::WriteLine(toBeTrimed-&gt;Trim(L'w', L'o', L'l', L' '));</pre>
<p style="text-indent: 24pt">如果仅仅想要删除头部或者尾部中的一端，可以使用TrimStart或者TrimEnd函数。</p>
<p style="text-indent: 24pt">如果要在字符串的一端填充空格或其它字符（这一般用于以固定宽度靠左或靠右对齐输出文本），可使用PadLeft()和PadRight()函数。如果字符串长度大于指定的长度参数，则返回字符串为长度等于原来字符串的新字符串。</p><pre>String^ value = L"<span style="color: #8b0000">3.142</span>";
String^ leftPadded = value-&gt;PadLeft(10);	<span style="color: #008000">// Result is "    3.142"</span>
String^ rightPadded = value-&gt;PadRight(10);	<span style="color: #008000">// Result is "3.142    "</span>
String^ leftPadded2 = value-&gt;PadLeft(10, L'*');	<span style="color: #008000">// Result is "*****3.142"</span>
String^ rightPadded2= value-&gt;PadRight(10,L'#');	<span style="color: #008000">// Result is "3.142#####"</span></pre>
<p style="text-indent: 24pt">如果需要将字符串转换成大写或小写，可使用ToUpper()或ToLower函数。</p><pre>String^ proverb = L"<span style="color: #8b0000">Many hands make light work.</span>"
String^ upper = proverb-&gt;ToUpper();	<span style="color: #008000">// Result is "MANY HANDS MAKE LIGHT WORK."</span></pre>
<p style="text-indent: 24pt">如果需要在字符串中间插入一个字符串，可使用Insert()函数，第一个参数指定起始位置的索引，第二个参数指定要插入的字符串。</p><pre>String^ proverb = L"<span style="color: #8b0000">Many hands light work.</span>";
String^ newProverb = proverb-&gt;Insert(5, "<span style="color: #8b0000">deck </span>");</pre>
<p style="text-indent: 24pt">结果是</p><pre>Many deck hands make light work.</pre>
<p style="text-indent: 24pt">如果要用另一个字符替换字符串中指定的字符，或者用另一个子串替换字符串中给定的子串，可使用Replace()函数。</p><pre>String^ proverb = L"<span style="color: #8b0000">Many hands make light work.</span>"
Console::WriteLine(proverb-&gt;Replace(L' ', L'*');
Console::WriteLine(proverb-&gt;Replace(L"<span style="color: #8b0000">Many hands</span>", L"<span style="color: #8b0000">Press switch</span>");</pre>
<p style="text-indent: 24pt">输出为</p><pre>Many*hands*make*light*work.
Pressing switch make light work.</pre>
<h1>三、搜索字符串</h1>
<p style="text-indent: 24pt">如果需要测试字符串是否以给定的子串开始或结束，可使用StartWith()或EndWith()函数。要寻找的子串句柄作为参数传递给函数，返回bool值。</p><pre>String^ snetence = L"<span style="color: #8b0000">Hide, the cow's outside.</span>";
<span style="color: #0000ff">if</span>(sentence-&gt;StartWith(L"<span style="color: #8b0000">Hide</span>"))
        Console::WriteLine("<span style="color: #8b0000">The sentence starts with 'Hide'.</span>");</pre>
<p style="text-indent: 24pt">IndexOf()函数用于返回给定字符或子串在字符串中找到的第一个实例索引，如果未找到，则返回-1。</p><pre>String^ sentence = L"<span style="color: #8b0000">Hide, the cow's outside.</span>";
<span style="color: #0000ff">int</span> ePosition = sentence-&gt;IndexOf(L'e');	<span style="color: #008000">// Return 3</span>
<span style="color: #0000ff">int</span> thePosition = sentence-&gt;IndexOf(L"<span style="color: #8b0000">the</span>");	<span style="color: #008000">// Retuen 6</span></pre>
<p style="text-indent: 24pt">也可以指定IndexOf搜索的起始索引，这一般用于遍历整个字符串找出所有的实例，如下面的例子：</p><pre><span style="color: #0000ff">int</span> index = 0;
<span style="color: #0000ff">int</span> count = 0;
<span style="color: #0000ff">while</span>((index=words-&gt;IndexOf(word, index))&gt;=0)
{
    index += word-&gt;Length;
    count++;
}
Console::WriteLine(L"<span style="color: #8b0000">'{0}' was found {1} times in: {2}</span>", word, count, words);</pre>
<p style="text-indent: 24pt">LastIndexOf()函数类似于IndexOf()函数，不过它用于从字符串尾部或指定索引位置开始，倒着向头部搜索。注意：如果从尾部开始的索引值是words-&gt;Lenght-1。</p>
<p style="text-indent: 24pt">如果要搜索一个字符串数组中任意元素出现在字符串中的位置，可以使用IndexOfAny()函数。同样，它也有倒序搜索的版本。 下面的例子说明了IndexOfAny()的用法。下面的例子用于搜索字符串中的标点符号</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:9d340c6c-5d14-43db-bb93-9712e07b5d52" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_18.CPP] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_18.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;wchar_t&gt;^ punctuation = {L'"<span style="color: #8b0000">', L'\'', L'.', L',', L':',L'!', L'?'};</span>
	String^ sentence = L"<span style="color: #8b0000">\"It's chilly in here\", the boy 's mother said coldly.</span>";

	array&lt;wchar_t&gt;^ indicators = gcnew array&lt;wchar_t&gt;(sentence-&gt;Length){L' '};

	<span style="color: #0000ff">int</span> index = 0;
	<span style="color: #0000ff">int</span> count = 0;
	<span style="color: #0000ff">while</span>((index=sentence-&gt;IndexOfAny(punctuation, index))&gt;=0)
	{
		indicators[index] = L'^';
		++index;
		++count;
	}
	Console::WriteLine(L"<span style="color: #8b0000">There are {0} punctuation charactors in the string:</span>", count);
	Console::WriteLine(L"<span style="color: #8b0000">\n{0}\n{1}</span>", sentence, gcnew String(indicators));
    <span style="color: #0000ff">return</span> 0;
}
</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c049a6cc-7ef0-44ea-823d-93e4485dc7e2" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex4_18.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre>
<u><em>输出为</em></u></pre><pre>There are 6 punctuation charactors in the <span style="color: #0000ff">string</span>:
"<span style="color: #8b0000">It's chilly in here</span>", the boy 's mother said coldly.
^  ^                ^^         ^                    ^</pre><img src ="http://www.cppblog.com/golq/aggbug/89505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-07-07 23:39 <a href="http://www.cppblog.com/golq/archive/2009/07/07/89505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(三):数组</title><link>http://www.cppblog.com/golq/archive/2009/06/29/88733.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Sun, 28 Jun 2009 17:34:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/06/29/88733.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/88733.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/06/29/88733.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/88733.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/88733.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt">要学习数组，必须先了解跟踪句柄。</p> <h1>一、跟踪句柄</h1> <p style="text-indent: 24pt">跟踪句柄类似于本地C++指针，但也有很大区别。跟踪句柄确实存储着某个对象的地址，但当CLR压缩堆过程中改变了该对象的地址，则垃圾回收器自动更新句柄所包含的地址。我们不能像本地指针那样用跟踪句柄来执行地址的算术运算，也不允许对跟踪句柄进行强制类型转换。 </p> <p style="text-indent: 24pt">在CLR堆中创建的对象必须被跟踪句柄引用。所有属于引用类型的对象都存储在堆中，因此为引用这些对象所创建的变量都必须是跟踪句柄。例如，String类型是引用类型，因此引用String对象的变量必须是跟踪句柄。值类型默认分配在堆栈上，但也可以用gcnew操作符将其存储在堆上。此外必须注意，在堆上分配的变量——其中包括所有CLR引用类型——都不能在全局作用域内声明。 </p> <p style="text-indent: 24pt">通过在类型名称后加”^”符号，用于声明一个该类型的句柄。下面的例子声明了一个String类型的跟踪句柄proverb。 </p><pre>String^ proverb;</pre>
<p style="text-indent: 24pt">在声明时句柄时，系统自动为其分配一个空值，该句柄不引用任何对象。也可显示地将某个句柄置为空值: </p><pre>proverb = nullptr;</pre>
<p style="text-indent: 24pt">注意不能用0来表示空值。如果用0来初始化某个句柄，则0将自动转换为被引用类型的对象，而句柄则指向该对象。可以在声明句柄时显示的将其初始化：</p><pre>String^ saying = L"<span style="color: #8b0000">I used to think I was indecisive but now I??¡ê¡èm not so sure.</span>"; </pre>
<p style="text-indent: 24pt">该语句首先在堆上创建一个包含等号右边字符串的String对象，然后将该对象的地址存入saying中。注意字符串字面值的类型为const wchar_t*而非String。类String提供了这样的方法使得const wchar_t*类型的字符串可以用来创建String类型的对象。 </p>
<p style="text-indent: 24pt">下面这条语句创建了值类型的句柄：</p><pre><span style="color: #0000ff">int</span>^ value = 99; </pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该语句在堆上创建一个Int32型的值类型变量，然后将该变量的地址存入句柄value中。由于value是一种指针，因此不能直接参与算术运算，可使用*运算符对地址求值（类似于本地C++指针那样）: </p><pre><span style="color: #0000ff">int</span> result = 2*(*value)+15;</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于*value表示value所指向地址存储的数值，因此result的值为2*99+15=213。注意，当value作为运算式左值时，不需要*即可对value指向的变量赋值。 </p><pre><span style="color: #0000ff">int</span>^ result = 0;
result = 2*(*value)+15;</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先创建了一个指向数值0的句柄result。（该语句会触发一条编译器警告，提示不能利用0来将句柄初始化为空值。） </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第2条语句=号右边为数值，而左边为句柄，编译器将自动将右值赋予句柄所指向的对象，即将其转换为如下语句 </p><pre>*result = 2*(*value)+15;</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意，要采用上面的语句，result句柄必须实际定义过。如果仅仅声明了result，则会产生运行时错误 </p><pre><span style="color: #0000ff">int</span>^ result;
*result = 2*(*value)+15;
</pre>
<p></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是因为第二句要对地址result求值，即意味着result指向的对象已经存在，但实际并非如此，因为声明该对象时系统默认赋予其空值(nullptr)。在这种情况下，采用下面的方法就可以正常工作了 </p><pre><span style="color: #0000ff">int</span>^ result;
result = 2*(*value)+15; </pre>
<h1>二、数组</h1>
<h2>(一)数组句柄</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLR数组是分配在可回收垃圾堆上的。必须用array&lt;<em>typename</em>&gt;指出要创建的数组，同其它CLR堆上的对象一样，需要用句柄来访问它，例子如下： </p><pre>array&lt;<span style="color: #0000ff">int</span>&gt;^ data;</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数组句柄data可用于存储对元素类型为int的一维数组的引用。下面的例子声明了一个句柄，并新建一个CLR数组来对此句柄初始化。</p><pre>array&lt;<span style="color: #0000ff">int</span>&gt;^ data = gcnew array&lt;<span style="color: #0000ff">int</span>&gt;(100); </pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 和本地C++数组一样，CLR数组中元素的索引值也是从0开始的，可以通过[ ]访问数组元素。数组元素都是CLR对象，在上面的例子中数组元素为Int32型对象，它们在算术表达式中就像普通的整数类型一样。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Length属性是数组的一个重要属性，记录着数组元素的数量。保存了64位的数组长度。 </p><pre><span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;data-&gt;Length; i++)
	data[i] = 2*(i+1);</pre>
<p style="text-indent: 24pt">可以用for each循环遍历数组元素。</p><pre>array&lt;<span style="color: #0000ff">int</span>&gt;^ value = {3, 5, 6, 8, 6};
<span style="color: #0000ff">for</span> each(<span style="color: #0000ff">int</span> item in value)
{
	item = 2*item + 1;
	Console::WriteLine("<span style="color: #8b0000">{0, 5}</span>", item);
}</pre>
<p style="text-indent: 24pt">该循环输出5字符宽度的字段，以右对齐的方式输出当前元素的计算结果，输出如下： </p><pre>    7   11   13   17   13 </pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数组句柄可以被重新赋值，只要保持数组元素类型和维数（等级）不变即可，在前面例子中的数组句柄data指向一个int类型的一维数组，可以重新给它赋值，使其指向另外的int类型1维数组： </p><pre>data = gcnew array&lt;<span style="color: #0000ff">int</span>&gt;(45);</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数组可以在创建时通过元素列表初始化，下例在CLR堆上创建了一个double类型的数组，并将引用赋值给了数组句柄： </p><pre>array&lt;<span style="color: #0000ff">double</span>&gt;^ sample = {3.4, 2.3, 6.8, 1.2, 5.5, 4.9, 7.4, 1.6};
</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果在声明数组句柄时不进行初始化，那么在给句柄赋值时不能采用上面的方法直接用元素列表用作右值，而必须采用显示创建的方式。即不能 </p><pre>array&lt;<span style="color: #0000ff">double</span>&gt;^ sample;
sample = {3.4, 2.3, 6.8, 1.2, 5.5, 4.9, 7.4, 1.6}
</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而必须采用如下方式 </p><pre>array&lt;<span style="color: #0000ff">double</span>&gt;^ sample;
sample = gcnew array&lt;<span style="color: #0000ff">double</span>&gt;{3.4, 2.3, 6.8, 1.2, 5.5, 4.9, 7.4, 1.6}
</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于字符串数组，注意每一个元素也是引用类型，这是因为每一个元素String也是在CLR堆上创建的，因此也要用String^来访问它。 </p><pre>array&lt;String^&gt;^ names = {"<span style="color: #8b0000">Jack</span>", "<span style="color: #8b0000">John</span>", "<span style="color: #8b0000">Joe</span>", "<span style="color: #8b0000">Jessica</span>", "<span style="color: #8b0000">Jim</span>", "<span style="color: #8b0000">Joanna</span>"};
</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以用Array类静态函数Clear()对数组中的连续数组元素清零。 </p><pre>Array::Clear(samples, 0, samples-&gt;Length);</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Clear()函数的第一个参数是被清零的数组，第二个参数是要清除地第一个元素的索引，第三个参数为要清除地元素数量。因此上述语句将samples数组的所有元素都置为0。如果Clear()清除的是某个跟踪句柄，则句柄所对应的元素都被应用Clear()函数。如果元素为bool型，则被置为false。 </p>
<h2>(二)数组排序</h2>
<p style="text-indent: 24pt">Array类还定义了一个Sort()静态函数，可用于对数组进行排序。如果以数组句柄作为参数，则对整个数组排序。如果要对数组部分排序，则还需要增加元素起始索引及数量，如下例</p><pre>array&lt;<span style="color: #0000ff">int</span>&gt;^ samples = {27, 3, 54, 11, 18, 2, 16};
Array::Sort(samples, 2, 3);</pre>
<p style="text-indent: 24pt">排序后数组元素变为{27, 3, <strong>11, 18, 54</strong>, 2, 16} </p>
<p style="text-indent: 24pt">Sort函数还有很多其它版本，下面的例子展示了如何排序两个相关的数组，即第一个数组中的元素是第二个数组对应元素的键。对第一个数组排序后，可对第二个数组进行相应的调整，使得键与值相互对应。</p>
<p style="text-indent: 24pt">Sort()函数对2个数组排序时，用第一个数组参数来确定两个数组的顺序，以此保持2个数组元素对应关系不变。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2c47fe26-c379-4ece-a716-c4c33cc7eb7d" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_13.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_13.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;String^&gt;^ names = { "<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Mary</span>", "<span style="color: #8b0000">Eve</span>", "<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Al</span>" };
	array&lt;<span style="color: #0000ff">int</span>&gt;^ weights = {103, 168, 128, 115, 180, 176};

	Array::Sort(names, weights);
	<span style="color: #0000ff">for</span> each( String^ name in names )
		Console::Write(L"<span style="color: #8b0000">{0, 10}</span>", name);
	Console::WriteLine();
	
	<span style="color: #0000ff">for</span> each(<span style="color: #0000ff">int</span> weight in weights)
		Console::Write(L"<span style="color: #8b0000">{0, 10}</span>", weight);
	Console::WriteLine();
	
	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:eebd7740-a4a7-4491-ab82-bd00efc32615" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex4_13.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre>输出为： </pre><pre>Al Bill Eve Jill Mary Ted 
176 180 115 103 128 168 </pre>
<h2>(三)数组搜索</h2>
<p style="text-indent: 24pt">Array类还提供了函数BinarySearch()以使用对分法搜索算法，对一维数组或给定范围内搜索特定元素的索引位置。使用该函数要求数组必须是顺序排列的，因此在搜索之前必须对数组进行排序。</p><pre>array&lt;<span style="color: #0000ff">int</span>&gt;^ value = { 23, 45, 68, 94, 123, 150, 203, 299 };
<span style="color: #0000ff">int</span> toBeFound = 127;
<span style="color: #0000ff">int</span> position = Array::BinarySearch(value, toBeFound);
<span style="color: #0000ff">if</span>(position&lt;0)
        Console::WriteLine(L"<span style="color: #8b0000">{0} was not found.</span>", toBeFound);
<span style="color: #0000ff">else</span>
        Console::WriteLine(L"<span style="color: #8b0000">{0} was found at index position {1}</span>", toBeFound, position);
</pre>
<p style="text-indent: 24pt">Array::BinarySearch()的第一个参数是被搜索数组的句柄，第二个参数是要查找的内容，返回值为int类型的数值。如果返回值小于0则说明未找到。如果要指定搜索范围，则需要传递4个参数，其中第2参数为搜索起始索引，第3参数为搜索的元素数量，第4个是要搜索的内容。下面的代码从第4个元素开始，一直搜索到结束位置。</p><pre>array&lt;<span style="color: #0000ff">int</span>&gt;^ value = { 23, 45, 68, 94, 123, 150, 203, 299 };
<span style="color: #0000ff">int</span> toBeFound = 127;
<span style="color: #0000ff">int</span> position = Array::BinarySearch(value, 3, 6, toBeFound);    </pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6ce0e592-f873-4f0f-8938-b87bb0c701d0" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_14.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_14.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;String^&gt;^ names = { "<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Mary</span>", "<span style="color: #8b0000">Eve</span>", "<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Al</span>", "<span style="color: #8b0000">Ned</span>", "<span style="color: #8b0000">Zoe</span>", "<span style="color: #8b0000">Dan</span>", "<span style="color: #8b0000">Jean</span>" };
	array&lt;<span style="color: #0000ff">int</span>&gt;^ weights = {103, 168, 128, 115, 180, 176, 209, 98, 190, 130};
	array&lt;String^&gt;^ toBeFound = {"<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Eve</span>", "<span style="color: #8b0000">Al</span>", "<span style="color: #8b0000">Fred</span>"};
	
	<span style="color: #0000ff">int</span> result = 0;
	Array::Sort(names, weights);

	<span style="color: #0000ff">for</span> each( String^ name in toBeFound )
	{
		result = Array::BinarySearch(names, name);
		<span style="color: #0000ff">if</span>(result&lt;0)
			Console::WriteLine(L"<span style="color: #8b0000">{0} was not found.</span>", name);
		<span style="color: #0000ff">else</span>
			Console::WriteLine(L"<span style="color: #8b0000">{0} weights {1} lbs.</span>", name, weights[result]);
	}

	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:8a543ff5-47e5-4628-b90c-cfc58422be08" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_14.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当搜索不到目标时，Array::BinarySearch()函数输出的并非任意负数，而是第一个大于该目标的元素索引值的按位补码。利用该方法，可以不打乱顺序在数组中插入新值。如，我们希望插入”Fred”到names数组中</p><pre>array&lt;String^&gt;^ names = { "<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Mary</span>", "<span style="color: #8b0000">Eve</span>", "<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Al</span>", "<span style="color: #8b0000">Ned</span>", "<span style="color: #8b0000">Zoe</span>", "<span style="color: #8b0000">Dan</span>", "<span style="color: #8b0000">Jean</span>" }
Array::Sort(names);
String^ name = L"<span style="color: #8b0000">Fred</span>";
<span style="color: #0000ff">int</span> position = Array::BinarySearch(names, name);
<span style="color: #0000ff">if</span>(position&lt;0)
position = ~position;</pre>
<p style="text-indent: 24pt">此时，position保存的是大于Fred的第一个元素的位置，该数值可用于插入新值。</p><pre>array&lt;String^&gt;^ newNames = gcnew array&lt;String^&gt;(names-&gt;Length+1);
<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0;i&lt;position;i++)
	newNames[i] = names[i];
newNames[position] = name;

<span style="color: #0000ff">if</span>(position&lt;name-&gt;Length)
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=position; i&lt;names-&gt;Length; i++)
		newNames[i+1] = names[i];
names = nullptr;</pre>
<p style="text-indent: 24pt">注意：最后一句用于删除names数组。 </p>
<h2>(四)多维数组</h2>
<p style="text-indent: 24pt">C++/CLI中可以创建多维数组，最大维数32维。与ISO/ANSI C++不同的是，C++/CLI中的多维数组并非数组的数组，而是真正的多维数组，创建整数多维数组方法如下：</p><pre>array&lt;<span style="color: #0000ff">int</span> 2&gt;^ value = gcnew array&lt;<span style="color: #0000ff">int</span>, 2&gt;(4, 5);</pre>
<p style="text-indent: 24pt">上面的代码创建了一个二维数组，四行五列，共20个元素。访问的方法是利用多个用逗号分隔的索引值来访问每一个元素，而不能用一个索引值访问一行</p><pre><span style="color: #0000ff">int</span> nrows = 4;
<span style="color: #0000ff">int</span> ncols = 5;
array&lt;<span style="color: #0000ff">int</span>, 2&gt;^ value = gcnew array&lt;<span style="color: #0000ff">int</span>, 2&gt;(nrows, ncols);
<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;nrows; i++)
<span style="color: #0000ff">    for</span>(<span style="color: #0000ff">int</span> j=0; j&lt;ncols; j++)
        value[i, j] = (i+1)*(j+1);
</pre>
<p style="text-indent: 24pt">上面的代码利用循环给二维数组value赋值。这里访问二维数组元素的符号与本地C++不同：后者实际上是数组的数组，而C++/CLI是真正的二维数组，不能用一个索引值来访问二维数组，那样是没有意义的。数组的维数被称为等级，上面value数组的等级为2。而本地C++数组的等级始终为1。当然，在C++/CLI中也可以定义数组的数组，方法见下例</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:efe6a430-e99d-427f-88cb-aaddcd62a6b6" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_15.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	<span style="color: #0000ff">const</span> <span style="color: #0000ff">int</span> SIZE = 12;
	array&lt;<span style="color: #0000ff">int</span>, 2&gt;^ products = gcnew array&lt;<span style="color: #0000ff">int</span>, 2&gt;(SIZE, SIZE);
	
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;SIZE; i++)
		<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> j=0; j&lt;SIZE; j++)
			products[i, j] = (i+1)*(j+1);
	Console::WriteLine(L"<span style="color: #8b0000">Here is the {0} times table:</span>", SIZE);

	<span style="color: #008000">// Write horizontal divider line</span>
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;=SIZE; i++)
		Console::Write(L"<span style="color: #8b0000">_____</span>");
	Console::WriteLine();

	<span style="color: #008000">// Write top line of table</span>
	Console::Write(L"<span style="color: #8b0000">    |</span>");
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=1; i&lt;=SIZE; i++)
		Console::Write("<span style="color: #8b0000">{0, 3} |</span>", i);
	Console::WriteLine();

	<span style="color: #008000">// Write horizontal divider line with verticals</span>
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;=SIZE; i++)
		Console::Write("<span style="color: #8b0000">____|</span>", i);
	Console::WriteLine();

	<span style="color: #008000">// Write remaining lines</span>
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;SIZE; i++)
	{
		Console::Write(L"<span style="color: #8b0000">{0, 3} |</span>", i+1);
		<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> j=0; j&lt;SIZE; j++)
			Console::Write("<span style="color: #8b0000">{0, 3} |</span>", products[i, j]);
		Console::WriteLine();
	}

	<span style="color: #008000">// Write horizontal divider line</span>
	<span style="color: #0000ff">for</span>(<span style="color: #0000ff">int</span> i=0; i&lt;=SIZE; i++)
		Console::Write("<span style="color: #8b0000">_____</span>", i);
	Console::WriteLine();
	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:72e341ac-0fcd-49e6-9bc6-ebcc2f5053c3" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex4_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt">上面的例子创建了一个12x12的乘法表，输出如下：</p><pre>Here is the 12 times table:
_________________________________________________________________
    |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 |
____|____|____|____|____|____|____|____|____|____|____|____|____|
  1 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 |
  2 |  2 |  4 |  6 |  8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 |
  3 |  3 |  6 |  9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 |
  4 |  4 |  8 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 |
  5 |  5 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 |
  6 |  6 | 12 | 18 | 24 | 30 | 36 | 42 | 48 | 54 | 60 | 66 | 72 |
  7 |  7 | 14 | 21 | 28 | 35 | 42 | 49 | 56 | 63 | 70 | 77 | 84 |
  8 |  8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 88 | 96 |
  9 |  9 | 18 | 27 | 36 | 45 | 54 | 63 | 72 | 81 | 90 | 99 |108 |
 10 | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 |100 |110 |120 |
 11 | 11 | 22 | 33 | 44 | 55 | 66 | 77 | 88 | 99 |110 |121 |132 |
 12 | 12 | 24 | 36 | 48 | 60 | 72 | 84 | 96 |108 |120 |132 |144 |
_________________________________________________________________
</pre>
<p style="text-indent: 24pt">其中创建二维数组的代码如下：</p><pre><span style="color: #0000ff">const</span> <span style="color: #0000ff">int</span> SIZE = 12;
array&lt;<span style="color: #0000ff">int</span>, 2&gt;^ products = gcnew array&lt;<span style="color: #0000ff">int</span>, 2&gt;(SIZE, SIZE);</pre>
<p style="text-indent: 24pt">第一行定义了一个整型常量SIZE，用于指定每一维数组的元素数量，第二行代码定义了一个等级2的数组，为12x12大小，该数组用于存储12x12的乘法表乘积。然后在嵌套循环中给数组赋值，大部分代码用于格式化输出以使其更加美观，这里就不再说明。</p>
<h2>(五)数组的数组</h2>
<p style="text-indent: 24pt">如果数组的元素是引用数组的跟踪句柄，那么就可以创建数组的数组。同时，每一维数组的长度可以不同，即所谓的“锯齿形数组”。例如，用ABCDE来表示学生的成绩等级，根据等级分组存储班内学生的姓名，则可以创建一个包含5个元素的数组，每个元素为一个姓名数组（即字符串数组）</p><pre>array&lt;array&lt;String ^&gt;^&gt;^ grades = gcnew array&lt;array&lt;String^&gt;^&gt;(5)</pre>
<p style="text-indent: 24pt">利用上面创建的数组，然后可以创建5个姓名数组了</p><pre>grades[0] = gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Louise</span>", "<span style="color: #8b0000">Jack</span>"};
grades[1] = gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Mary</span>", "<span style="color: #8b0000">Ben</span>", "<span style="color: #8b0000">Joan</span>"};
grades[2] = gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Will</span>", "<span style="color: #8b0000">Phil</span>"};
grades[3] = gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Ned</span>", "<span style="color: #8b0000">Fred</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Jed</span>", "<span style="color: #8b0000">Ed</span>"};
grades[4] = gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Dan</span>", "<span style="color: #8b0000">Ann</span>"};</pre>
<p style="text-indent: 24pt">grades[n]访问grades数组的第n个元素，而各元素为指向String^类型数组的句柄，因此上面的语句用于创建了String对象句柄的数组，并将创建数组的地址赋值给了grades数组元素。同时，这些字符串数组的长度是不同的。</p>
<p style="text-indent: 24pt">上面的语句也可以用一个初始化语句来实现</p><pre>array&lt;array&lt;String^&gt;^&gt;^ grades = gcnew array&lt;array&lt;String^&gt;^&gt;
{
    gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Louise</span>", "<span style="color: #8b0000">Jack</span>"},
    gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Maray</span>", "<span style="color: #8b0000">Ben</span>", "<span style="color: #8b0000">Joan</span>"},
    gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Will</span>", "<span style="color: #8b0000">Phil</span>"},
    gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Ned</span>", "<span style="color: #8b0000">Fred</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Jed</span>", "<span style="color: #8b0000">Ed</span>"},
    gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Dan</span>", "<span style="color: #8b0000">Ann</span>"},
};</pre>
<p style="text-indent: 24pt">注意：元素的初值必须写在花括号里。</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6730aeb0-6242-40c6-b420-d207afd488c7" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex4_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex4_16.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	array&lt;array&lt;String^&gt;^&gt;^ grades = gcnew array&lt;array&lt;String^&gt;^&gt;
		{
			gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Louise</span>", "<span style="color: #8b0000">Jack</span>"},
			gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Bill</span>", "<span style="color: #8b0000">Maray</span>", "<span style="color: #8b0000">Ben</span>", "<span style="color: #8b0000">Joan</span>"},
			gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Jill</span>", "<span style="color: #8b0000">Will</span>", "<span style="color: #8b0000">Phil</span>"},
			gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Ned</span>", "<span style="color: #8b0000">Fred</span>", "<span style="color: #8b0000">Ted</span>", "<span style="color: #8b0000">Jed</span>", "<span style="color: #8b0000">Ed</span>"},
			gcnew array&lt;String^&gt;{"<span style="color: #8b0000">Dan</span>", "<span style="color: #8b0000">Ann</span>"}
		};
	
	wchar_t gradeLetter = 'A';
	<span style="color: #0000ff">for</span> each(array&lt;String^&gt;^ grade in grades)
	{
		Console::WriteLine(L"<span style="color: #8b0000">Students with Grade {0}:</span>", gradeLetter++);
		<span style="color: #0000ff">for</span> each(String^ student in grade)
			Console::Write("<span style="color: #8b0000">{0, 12}</span>", student);
		Console::WriteLine();
	}
	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5eaa81fb-c9c2-4c8c-84dc-5428d0a0e13b" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex4_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt">输出为</p><pre>Students with Grade A:
      Louise        Jack
Students with Grade B:
        Bill       Maray         Ben        Joan
Students with Grade C:
        Jill        Will        Phil
Students with Grade D:
         Ned        Fred         Ted         Jed          Ed
Students with Grade E:
         Dan         Ann</pre><img src ="http://www.cppblog.com/golq/aggbug/88733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-06-29 01:34 <a href="http://www.cppblog.com/golq/archive/2009/06/29/88733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(二):控制与循环</title><link>http://www.cppblog.com/golq/archive/2009/06/27/88645.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Sat, 27 Jun 2009 08:46:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/06/27/88645.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/88645.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/06/27/88645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/88645.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/88645.html</trackback:ping><description><![CDATA[<h1>一、基本控制结构</h1> <p style="text-indent: 24pt">ISO/ANSI C++中的控制与循环全部适用于C++/CLI。下例展示了C++/CLI控制台程序中的控制循环：</p> <h2><em><u>例子：基本循环控制</u></em></h2> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:51a1b54f-086a-48f2-b1f6-4ee9a7947e98" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex3_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex3_15.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
    wchar_t letter;

    Console::Write(L"<span style="color: #8b0000">Enter a letter:</span>");
    letter = Console::Read();

    <span style="color: #0000ff">if</span>(letter&gt;='A')
        <span style="color: #0000ff">if</span>(letter&lt;='Z')
        {
            Console::WriteLine(L"<span style="color: #8b0000">You entered a captial letter.</span>");
            <span style="color: #0000ff">return</span> 0;
        }

    <span style="color: #0000ff">if</span>(letter&gt;='a')
        <span style="color: #0000ff">if</span>(letter&lt;='z')
        {
            Console::WriteLine(L"<span style="color: #8b0000">You entered a small letter.</span>");
            <span style="color: #0000ff">return</span> 0;
        }

    Console::WriteLine(L"<span style="color: #8b0000">You did not enter a letter.</span>");
    <span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4fbddd37-75c5-4813-8c7b-a1940ab131d0" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex3_15.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt"> letter被声明为wchar_t类型，映射为C++/CLI中的System::Char类型，它具有一些特殊的功能，其中包括将字符代码转换为大写和小写的函数：Char::ToUpper（）和Char::ToLower()，被转换的函数作为参数被传递给它:</p><pre>wchar_t uppercaseLetter = Char::ToUpper(letter);</pre>
<p style="text-indent: 24pt"> 此外还包括检测字母是否大写或小写的函数:IsUpper()和IsLower()，因此上例可改为</p><pre>wchar_t letter; 
wchar_t upper; 

Console::Write(L"<span style="color: #8b0000">Enter a letter:</span>"); 
letter = Console::Read(); 
upper = Char::ToUpper(letter); 

<span style="color: #0000ff">if</span>(upper&gt;='A' &amp;&amp; upper&lt;='Z') 
    Console::WriteLine(L"<span style="color: #8b0000">You entered a {0} letter.</span>", Char::IsUpper(letter) ? "<span style="color: #8b0000">Capital</span>":"<span style="color: #8b0000">Small</span>"); 
<span style="color: #0000ff">else</span> 
    Console::WriteLine(L"<span style="color: #8b0000">You entered a small letter.</span>");</pre>
<p style="text-indent: 24pt"> Console::ReadKey()函数用于测试按键，并将结果存储在ConsoleKeyInfo类对象里。该类有3个可访问属性用于帮助确定被按下的键是哪个或哪些键。属性Key识别被按下的键是哪个，属性KeyChar是被按键的Unicode字符码，属性Modifiers表示Shift,Alt,Ctrl键的按位组合，它是定义在System命名空间中的枚举类型ConsoleModifiers的常量，包括Shift\Alt\Control。</p>
<p style="text-indent: 24pt">应该注意的是，在C++/CLI中枚举常量在用作数值之前必须被显示的强制转换为值类型（整数类型）</p>
<h4></h4>
<h2><em><u>例子：使用Console::ReadKey()函数</u></em></h2>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:67119a9f-0a48-4345-afc8-d63e2d656e32" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex3_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex3_16.cpp : main project file.</span>

#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	ConsoleKeyInfo keyPress;

	Console::WriteLine(L"<span style="color: #8b0000">Press a key combination - press Escape to quit.</span>");
	<span style="color: #0000ff">do</span>{
		keyPress = Console::ReadKey(<span style="color: #0000ff">true</span>);
		Console::Write(L"<span style="color: #8b0000">You pressed</span>");
		<span style="color: #0000ff">if</span>(safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(keyPress.Modifiers)&gt;0)
			Console::Write(L"<span style="color: #8b0000"> {0}</span>", keyPress.Modifiers);
		Console::WriteLine(L"<span style="color: #8b0000"> {0} which is the {1} character</span>", keyPress.Key, keyPress.KeyChar);
	}<span style="color: #0000ff">while</span>(keyPress.Key != ConsoleKey::Escape);
    <span style="color: #0000ff">return</span> 0;
}
</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7eb3432e-0ed1-45b8-a5b1-4f5130a6057e" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex3_16.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt"> 该程序的输入示例如下： </p><pre>Press a key combination - press Escape to quit.
You pressed Enter which is the  character
You pressed Spacebar which is the   character
You pressed Spacebar which is the   character</pre>
<p style="text-indent: 24pt"> 从输出中可以看出，当不只一个键被按下时，用一条语句就可以得到所有的键。这是因为Modifiers枚举类型是用FlagsAttribute属性定义的，该属性表明这种枚举类型是一组唯一的位标志。这使得该枚举类型的变量可以由若干与在一起的标志位组成，而Write()或WriteLine()函数可以识别并输出各标志位。 </p>
<h1>二、for each循环</h1>
<p style="text-indent: 24pt"> 以例子开始</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:956e7ca7-a8a2-4ce9-b203-000336508821" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex3_17.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex3_17.cpp : main project file.</span>

#include "<span style="color: #8b0000">stdafx.h</span>"

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	<span style="color: #0000ff">int</span> volwels = 0;
	<span style="color: #0000ff">int</span> consonants = 0;
	String^ proverb = L"<span style="color: #8b0000">A nod is as good as a wink to a blind horse.</span>";

	<span style="color: #0000ff">for</span> each(wchar_t ch in proverb)
	{
		<span style="color: #0000ff">if</span>(Char::IsLetter(ch))
		{
			ch = Char::ToLower(ch);
			<span style="color: #0000ff">switch</span>(ch)
			{
			<span style="color: #0000ff">case</span> 'a': <span style="color: #0000ff">case</span> 'e': <span style="color: #0000ff">case</span> 'i': <span style="color: #0000ff">case</span> 'o': <span style="color: #0000ff">case</span> 'u':
				++volwels;
				<span style="color: #0000ff">break</span>;

			<span style="color: #0000ff">default</span>:
				++consonants;
				<span style="color: #0000ff">break</span>;
			}
		}
	}

	Console::WriteLine(proverb);
	Console::WriteLine(L"<span style="color: #8b0000">The proverb contains {0} volwels and {1} consonants.</span>",
		volwels, consonants);
    <span style="color: #0000ff">return</span> 0;
}
</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e6e492bc-0694-4a70-bf03-24eb0ef87923" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex3_17.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt"> 输出为：</p><pre>A nod is as good as a wink to a blind horse. 
The proverb contains 14 volwels <span style="color: #0000ff">and</span> 18 consanants. </pre>
<p style="text-indent: 24pt"> 注意：由于proverb字符串中的字符都是Unicode字符，因此用wchar_t（映射为Char类型）类型的变量来存储这些字符。变量ch为循环内的局部变量。</p><img src ="http://www.cppblog.com/golq/aggbug/88645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-06-27 16:46 <a href="http://www.cppblog.com/golq/archive/2009/06/27/88645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI学习入门(一)：基础</title><link>http://www.cppblog.com/golq/archive/2009/06/27/88644.html</link><dc:creator>英勇的近卫军</dc:creator><author>英勇的近卫军</author><pubDate>Sat, 27 Jun 2009 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/golq/archive/2009/06/27/88644.html</guid><wfw:comment>http://www.cppblog.com/golq/comments/88644.html</wfw:comment><comments>http://www.cppblog.com/golq/archive/2009/06/27/88644.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/golq/comments/commentRss/88644.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/golq/services/trackbacks/88644.html</trackback:ping><description><![CDATA[<p style="text-indent: 24pt"><font color="#ffff80">从今日开始，将前期学习《Visual C++ 2005入门经典》（Ivor Horton著 清华大学出版社出版）的相关笔记整理到随笔中，希望能和C++/CLI爱好者分享学习过程中的心得。文中主要内容和例子摘自原书相关章节，如有侵权，请留言或来信告知。</font></p> <p style="text-indent: 24pt">相比于ISO/ANSI C++而言，C++/CLI进行了大量的扩充，并且提供了大量的附加功能。主要包括:</p> <ul> <li> <div style="text-indent: 24pt">在C++/CLI程序中，所有ISO/ANSI基本数据类型都可以使用，但在一些特殊的上下文环境中，它们具有一些额外属性； </div> <li> <div style="text-indent: 24pt">在控制台程序中，C++/CLI对键盘和命令行输出提供了自己的机制；</div> <li> <div style="text-indent: 24pt">C++/CLI中引入了safe_cast运算符，确保强制类型转换操作能够生成可检验的代码；</div> <li> <div style="text-indent: 24pt">C++/CLI提供了另外一种基于类的枚举功能，其灵活性超过了ISO/ANSI C++中的enum声明。</div></li></ul> <h1>一、基本数据类型</h1> <p style="text-indent: 24pt">C++/CLI中包括了所有ISO/ASNI C++中的基本数据类型，算术运算也和本地C++完全一样。除此之外，C++/CLI中还定义了2种整数类型，如表1所示：</p> <p style="text-indent: 24pt">表1:C++/CLI新增基本数据类型</p> <table border="1" cellspacing="0" cellpadding="2" width="647"> <tbody> <tr> <td valign="top" width="181"> <p align="center"><strong>类型</strong></p></td> <td valign="top" width="85"> <p align="center"><strong>字节</strong></p></td> <td valign="top" width="379"> <p align="center"><strong>值域</strong></p></td></tr> <tr> <td valign="top" width="181"> <p align="center">long long</p></td> <td valign="top" width="85"> <p align="center">8</p></td> <td valign="top" width="379"> <p>从-9223372036854775808到9223372036854775807</p></td></tr> <tr> <td valign="top" width="181"> <p align="center">Unsigned long long</p></td> <td valign="top" width="85"> <p align="center">8</p></td> <td valign="top" width="379"> <p align="left">&nbsp; 从0到18446744073709551615</p></td></tr></tbody></table> <p style="text-indent: 24pt">指定long long数据类型时，需要在整数数值后面加LL或小写字母ll，如</p><pre>longlong big = 123456789LL;</pre>
<p style="text-indent: 24pt">指定unsinged long long类型时，需要在整数数值后面加ULL或小写字母ull，如</p><pre><span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">long</span> <span style="color: #0000ff">long</span> <span style="color: #0000ff">huge</span> = 123456789LL;</pre>
<p style="text-indent: 24pt">在C++/CLI中，每一个ISO/ANSI C++基本类型名称都映射到System命名空间中定义的值类类型。在C++/CLI程序中，ISO/ANSI C++基本类型名称都是CLI中对应值类类型的简略形式。表2给出了基本类型、占用内存以及对应的值类类型。</p>
<p style="text-indent: 24pt">表2：基本类型与CLI值类型</p>
<table border="1" cellspacing="0" cellpadding="2" width="329">
<tbody>
<tr>
<td valign="top" width="133">
<p align="center"><strong>基本类型</strong></p></td>
<td valign="top" width="53">
<p align="center"><strong>字节</strong></p></td>
<td valign="top" width="141">
<p align="center"><strong>CLI值类类型</strong></p></td></tr>
<tr>
<td valign="top" width="133">
<p align="center">bool<br>char<br>singed char<br>unsigned char<br>short<br>unsigned short<br>int<br>unsigned int<br>long<br>unsigned long<br>long long<br>unsigned long long<br>float<br>double<br>long double<br>wchar_t</p></td>
<td valign="top" width="53">
<p align="center">1<br>1<br>1<br>1<br>2<br>2<br>4<br>4<br>4<br>4<br>8<br>8<br>4<br>8<br>8<br>2</p></td>
<td valign="top" width="141">
<p align="left">System::Boolean<br>System::SByte<br>System::SByte<br>System::Byte<br>System::Int16<br>System::UInt16<br>System::Int32<br>System::UInt32<br>System::Int32<br>System::UInt32<br>System::Int64<br>System::UInt64<br>System::Single<br>System::Double<br>System::Double<br>System::Char</p></td></tr></tbody></table>
<p style="text-indent: 24pt">默认情况下，char类型被视为singed char，因此其关联的值类类型为System::SByte。如果编译选项/J，则char 默认为unsigned char，此时关联为System::Byte。System为根命名空间名，C++/CLI的值类类型在这个空间中定义。此外System空间中还定义了许多其他类型，如表示字符串的String类型、精确存储的十进制小数类型Decimal等等。 </p>
<p style="text-indent: 24pt">在C++/CLI中，关联的值类类型为基本类型添加了重要的附加功能。编译器在需要时，将安排原值与关联类型之间的自动转换，其中从原值转换为关联类型成为装箱(boxing)，反之称为拆箱(unboxing)。根据上下文环境，这些变量将表现为简单的值或者对象。 </p>
<p style="text-indent: 24pt">由于ISO/ANSI C++基本类型的名称是C++/CLI程序中值类类型名称的别名，所以原则上C++/CLI代码中可用任何一种名称。</p><pre><span style="color: #0000ff">int</span> count = 10; 
<span style="color: #0000ff">double</span> value = 2.5;</pre>
<p style="text-indent: 24pt">与下面的代码是等价的</p><pre>System::Int32 count = 10; 
System::Double value = 2.5;</pre>
<p style="text-indent: 24pt">上面2种代码是完全合法的，但应尽量使用基本类型名称，如int和double，而不是System::Int32和System::Double。这是因为上面描述的这种映射关系仅适用于Visual C++ 2005及以上版本的编译器，其他版本编译器未必实现这种映射关系。</p>
<p style="text-indent: 24pt">将基本类型转换为值类类型是C++/CLI的一个重要特征。在ISO/ANSI C++中基本类型与类类型完全不同，而在C++/CLI中，所有数据都以类类型的形式存储，包括值类型（存储在堆栈上）和引用类型（存储在堆上）2种。</p>
<h2><em><u>例子：Fruit CLR控制台项目</u></em></h2>
<p style="text-indent: 24pt">在Visual Studio 2005中创建CLR Console Application项目，输入名称Ex2_12，将生成如下文件</p><pre><span style="color: #008000">// Ex2_12.cpp : main project file. </span>
#include "<span style="color: #8b0000">stdafx.h</span>" 
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System; 
<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args) 
{ 
    Console::WriteLine(L"<span style="color: #8b0000">Hello World</span>"); 
    <span style="color: #0000ff">return</span> 0; 
}</pre>
<p style="text-indent: 24pt">main函数后的参数为命令行参数。然后按如下方式改写代码</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4964094c-9831-4168-921a-da24adaedf83" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex_12.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex2_12.cpp : main project file. </span>
#include "<span style="color: #8b0000">stdafx.h</span>" 
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System; 
<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args) 
{ 
    <span style="color: #0000ff">int</span> apples, oranges; 
    <span style="color: #0000ff">int</span> fruit; 

    apples = 5; 
    oranges = 6; 
    fruit = apples + oranges; 
    Console::WriteLine(L"<span style="color: #8b0000">\nOranges are not the only fruit ...</span>"); 
    Console::Write(L"<span style="color: #8b0000">- and we have </span>"); 
    Console::Write(fruit); 
    Console::Write(L"<span style="color: #8b0000"> fruit in all.\n</span>"); 

    <span style="color: #0000ff">return</span> 0; 
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:45cc2874-ded5-4b37-ad28-63528c78e738" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex_12.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p><font size="1"><font face="Tahoma"></font></font></p>
<p style="text-indent: 24pt">编译后执行得到如下输出： </p><pre>Oranges are <span style="color: #0000ff">not</span> the only fruit?- 
- <span style="color: #0000ff">and</span> we have 11 fuit in all. </pre>
<p style="text-indent: 24pt">与ISO/ANSI C++版本比较，变量的类型int将成为C++/CLI类型System::Int32。如果用System::Int32替换代码中的int，然后重新编译运行，结果将没有变化。</p>
<p style="text-indent: 24pt">WriteLine()函数为C++/CLI函数，定义在System命名空间的Console类中。Console表示标准输入输出流。Write()函数为该类的另一个输出函数，不会自动换行。下面专门讨论C++/CLI的控制台输入输出。 <font size="1"><font face="Tahoma"><em>&nbsp;&nbsp;&nbsp;&nbsp; </em></font></font></p>
<h1>二、控制台输出</h1>
<p style="text-indent: 24pt">C++/CLI中特有控制台格式化输出功能，例如可用下面的代码来输出字符串与变量混合文本。</p><pre>Console::WriteLine(L"<span style="color: #8b0000">There are {0} fruit.</span>", fruit);</pre>
<p style="text-indent: 24pt">Console::WriteLine()的第一个参数是L”There are {0} fruit.”，其中{0}为格式化占位符，表示在此处插入第二个参数的值，如果有更多需要插入的参数，则该参数对应的占位符编号继续增加：{1}、{2}、{3}…。在第一个字符串参数中，编号的顺序可以颠倒，如 </p><pre>Console::WriteLine(L"<span style="color: #8b0000">There are {1} packages weighting {0} pounds</span>", packageWeight, packageCount);</pre>
<p style="text-indent: 24pt">格式化占位符还可以控制显示的格式，如{1:F2}表示第2个参数显示成有2位小数的浮点数，冒号后的为格式规范</p><pre>Console::WriteLine(L"<span style="color: #8b0000">There are {0} packages weighting {1:F2} pounds </span>", packageCount, packageWeight);</pre>
<p style="text-indent: 24pt">输出为</p><pre>There are 25 packages weighting 7.50 pounds.       </pre>
<p style="text-indent: 24pt">一般说来，可以编写格式为{n,w:Axx}的格式规范，其中n为索引值，用于选择逗号后的第几个参数； A为单个字母，表示如何对变量格式化；xx为1个或2个数字，指定参数的精度；w为有符号整数，表示可选的字段宽度范围，如果w为+，则字段右对齐，如果w为-，则左对齐。如果数值的位置数小于w指定的位置数，则多出来的用空格填充，如果数值的位置数大于w指定的位置数，则忽略w的限定：</p><pre>Console::WriteLine(L"<span style="color: #8b0000">Packages: {0,3} Weight: {1,5£ºF2} pounds </span>", packageCount, packageWeight);</pre>
<p style="text-indent: 24pt">输出为（下划线表示空格填充位）：</p>
<p>Packages: _25 Weight: __7.50 pounds </p>
<p style="text-indent: 24pt">可选的格式说明符如表3所示</p>
<p style="text-indent: 24pt">表3：格式说明符</p>
<table border="1" cellspacing="0" cellpadding="2" width="593">
<tbody>
<tr>
<td valign="top" width="99">
<p align="center"><strong>格式说明符</strong></p></td>
<td valign="top" width="492">
<p align="center"><strong>说明</strong></p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">C或c</p></td>
<td valign="top" width="492">
<p>把值作为货币量输出</p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">D或d</p></td>
<td valign="top" width="492">
<p>把整数作为十进制值输出。如果指定的精度大于位数，则在数值的坐标填充0</p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">E或e</p></td>
<td valign="top" width="492">
<p>按照科学技术法输出浮点值</p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">F或f</p></td>
<td valign="top" width="492">
<p>把浮点数作为±####.##的定点数输出</p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">G或g</p></td>
<td valign="top" width="492">
<p>以最紧凑的形式输出，取决于是否指定了精度值，如果没有则适用默认精度</p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">N或n</p></td>
<td valign="top" width="492">
<p>把值作为定点十进制值输出，必要时以3位一组用逗号分隔</p></td></tr>
<tr>
<td valign="top" width="99">
<p align="center">X或x</p></td>
<td valign="top" width="492">把整数作为十六进制值输出。根据X或x，以大写或小写输出。</td></tr></tbody></table>
<p align="center"></p>
<p><strong><font size="1" face="Tahoma"></font></strong></p>
<h2><u><em>例子：计算地毯价格，演示CLR控制台程序的格式化输出</em></u> </h2>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e388b01f-2a92-46bc-9c0b-bdf26fb12572" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex_13.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex2_13.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;
<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	<span style="color: #0000ff">double</span> carpetPriceSqYd = 27.95;
	<span style="color: #0000ff">double</span> roomWidth = 13.5;			<span style="color: #008000">// in feet</span>
	<span style="color: #0000ff">double</span> roomLength = 24.75;			<span style="color: #008000">// in feet</span>
	<span style="color: #0000ff">const</span> <span style="color: #0000ff">int</span> feetPerYard = 3;
	<span style="color: #0000ff">double</span> roomWidthYard = roomWidth/feetPerYard;
	<span style="color: #0000ff">double</span> roomLengthYard = roomLength/feetPerYard;
	<span style="color: #0000ff">double</span> carpetPrice = roomWidthYard*roomLengthYard*carpetPriceSqYd;

	Console::WriteLine(L"<span style="color: #8b0000">Room is {0:F2} yards by {1:F2} yards</span>",
		roomWidthYard, roomLengthYard);
	Console::WriteLine(L"<span style="color: #8b0000">Room area is {0:F2} square yards</span>", 
		roomWidthYard*roomLengthYard);
	Console::WriteLine(L"<span style="color: #8b0000">Carpet price is ${0:F2}</span>", carpetPrice);
	<span style="color: #0000ff">return</span> 0;
}</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e48c7945-f111-41f4-9a95-9ac58c2d0961" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex_13.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p><font size="1"><font face="Tahoma"><u><em></em></u></font></font></p>
<h1>三、控制台输入</h1>
<p style="text-indent: 24pt">.Net Framework的控制台键盘输入功能有限，可以适用Console::ReadLine()函数把整行输入作为字符串读取，或者使用Console::Read()读取单个字符，还可以适用Console::ReadKey()读取按键。ReadLine()的例子如下：</p>
<p style="text-indent: 24pt">ReadLine()用于将整行文本存入字符串中，按下Enter键时，文本结束。变量line为String^型，表示String数据类型的引用，line为Console::ReadLine()函数读入字符串的引用。</p><pre>String^ line = Console::ReadLine();</pre>
<p style="text-indent: 24pt">Read()用于逐字符的读入输入数据，并将其转换成对应的数字值。ReadKey的例子如下：</p><pre><span style="color: #0000ff">char</span> ch = Console::Read();</pre>
<p style="text-indent: 24pt">ReadKey()用于读取按键值，并返回ConsoleKeyInfo对象，该为对象定义在System命名空间中的值类型。参数true表示按键不在命令行上显示出来，false则表示显示按键回显。按键对应的字符可用ConsoleKeyInfo对象的KeyChar得到。</p><pre>ConsoleKeyInfo keyPressed = Console::ReadKey(<span style="color: #0000ff">true</span>);
Console::WriteLine(L"<span style="color: #8b0000">The key press corresponds to the character: {0}</span>", keyPress.KeyChar);</pre>
<p style="text-indent: 24pt">尽管C++/CLI控制台程序中不能格式化输入，但输入一般都通过窗口组件得到，因此这仅仅是一个小缺陷。</p>
<p><font size="1" face="Tahoma"></font></p>
<p></p>
<h1>四、强制类型转换safe_cast</h1>
<p style="text-indent: 24pt">在CLR环境中safe_cast用于显示的强制类型转换。safe_cast用于将一种类型转换为另一种类型，在不成功时能够抛出异常，因此在C++/CLI中使用safe_cast是比较好的选择。其用法和static_cast一样： </p><pre><span style="color: #0000ff">double</span> value1 = 10.5; 
<span style="color: #0000ff">double</span> value2 = 15.5; 
<span style="color: #0000ff">int</span> whole_number = safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(value1) + safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(value2);</pre>
<h1>五、枚举</h1>
<p style="text-indent: 24pt">C++/CLI的枚举与ISO/ANSI C++有较大的区别。下例为C++/CLI中的一个枚举类型：该语句定义了一个枚举类型Suit，该类型的变量只能被赋值枚举定义中的值，且必须用枚举类型名称限定枚举常数。</p><pre><span style="color: #0000ff">enum</span> <span style="color: #0000ff">class</span> Suit {Clubs, Diamonds, Hearts, Spades};
Suit suit = Suit::Diamonds;</pre>
<p style="text-indent: 24pt">注意class关键字跟在enum之后。说明该枚举类型为C++/CLI，该关键字还表明在定义中规定的常量: Clubs\Diamonds\Hearts\Spades都是类对象而非ISO/ANSI C++中的基本类型（整型）值。实际上，默认情况下这些都是Int32类型的对象。</p>
<p style="text-indent: 24pt">由于C++/CLI枚举定义中的变量都是类对象，因此不能在函数内部定义。</p>
<h2>(一）指定枚举常量的类型</h2>
<p style="text-indent: 24pt">枚举中常量的类型可以是下表中任一基本类型：</p>
<table border="0" cellspacing="0" cellpadding="0" width="801">
<tbody>
<tr>
<td valign="top" width="150">
<p><font size="1">short</font></p></td>
<td valign="top" width="127">
<p><font size="1">int</font></p></td>
<td valign="top" width="140">
<p><font size="1">long</font></p></td>
<td valign="top" width="140">
<p><font size="1">long long</font></p></td>
<td valign="top" width="123">
<p><font size="1">signed char</font></p></td>
<td valign="top" width="119">
<p><font size="1">char</font></p></td></tr>
<tr>
<td valign="top" width="149">
<p><font size="1">unsigned short</font></p></td>
<td valign="top" width="127">
<p><font size="1">unsigned int</font></p></td>
<td valign="top" width="140">
<p><font size="1">unsigned long</font></p></td>
<td valign="top" width="140">
<p><font size="1">unsigned long long</font></p></td>
<td valign="top" width="123">
<p><font size="1">unsigned char</font></p></td>
<td valign="top" width="119">
<p><font size="1">bool</font></p></td></tr></tbody></table>
<p><font size="1" face="Tahoma"></font></p>
<p></p>
<p><em><u></u></em></p>
<p style="text-indent: 24pt">要指定一个枚举常量的类型，可以在枚举类型名称之后写入常量类型名称（要用冒号隔开），下例枚举类型中的常量为Char类型，对应的基本类型为char。其中第一个常量默认情况下对应于代码值0，后面的依次递增。</p><pre><span style="color: #0000ff">enum</span> <span style="color: #0000ff">class</span> Face:<span style="color: #0000ff">char</span> { Ace,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King};</pre>
<h2>(二)指定枚举常量的值</h2>
<p style="text-indent: 24pt"> 可以赋予枚举类型定义中的一个或全部常数对应的值，下例使得Ace获得1，Two获得2，其余依此类推，直到King=13。 </p><pre><span style="color: #0000ff">enum</span> <span style="color: #0000ff">class</span> Face:<span style="color: #0000ff">char</span> { Ace=1,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King};</pre>
<p style="text-indent: 24pt"> 如果想让Ace获得最大值，则可以如下定义： </p><pre><span style="color: #0000ff">enum</span> <span style="color: #0000ff">class</span> Face:Char { Ace=14,Two=2,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King};</pre>
<h2><em><u>例子：使用枚举类型</u></em></h2>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ceb6503e-bfbb-4fae-b7b3-85fa61148745" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::开始==>> [Ex_14.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div><pre><span style="color: #008000">// Ex2_14.cpp : main project file.</span>
#include "<span style="color: #8b0000">stdafx.h</span>"
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> System;

<span style="color: #0000ff">enum</span> <span style="color: #0000ff">class</span> Suit {Clubs, Diamonds, Hearts, Spades};

<span style="color: #0000ff">int</span> main(array&lt;System::String ^&gt; ^args)
{
	Suit suit = Suit::Clubs;
	<span style="color: #0000ff">int</span> value = safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(suit);

	Console::WriteLine(L"<span style="color: #8b0000">Suit is {0} and the value is {1}</span>", suit, value);
	suit = Suit::Diamonds;
	value = safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(suit);
	Console::WriteLine(L"<span style="color: #8b0000">Suit is {0} and the value is {1}</span>", suit, value);
	suit = Suit::Hearts;
	value = safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(suit);
	Console::WriteLine(L"<span style="color: #8b0000">Suit is {0} and the value is {1}</span>", suit, value);
	suit = Suit::Spades;
	value = safe_cast&lt;<span style="color: #0000ff">int</span>&gt;(suit);
	Console::WriteLine(L"<span style="color: #8b0000">Suit is {0} and the value is {1}</span>", suit, value);
    <span style="color: #0000ff">return</span> 0;
}
</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:72098f41-becd-49c2-b25d-c0add02b5934" class="wlWriterEditableSmartContent">- - - - - - - - - - - - - - - - <<== 华丽的分割线 ::结束==>> [Ex_14.cpp] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - </div>
<p style="text-indent: 24pt">该例子的输出为</p><pre>Suit is Clubs <span style="color: #0000ff">and</span> the value is 0 
Suit is Diamonds <span style="color: #0000ff">and</span> the value is 1 
Suit is Hearts <span style="color: #0000ff">and</span> the value is 2 
Suit is Spades <span style="color: #0000ff">and</span> the value is 3 </pre>
<p style="text-indent: 24pt">例子说明 </p>
<ul>
<li>Suit为枚举类型，不能在函数main()内部定义，因此只能定义为全局作用域内。 
<li>必须用类型名称Suit限定枚举常量，如Suit::Clubs，否则编译器将无法识别。 
<li>变量suit的值为类对象，要获取其值必须显示的将其转换成int类型。 </li></ul><img src ="http://www.cppblog.com/golq/aggbug/88644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/golq/" target="_blank">英勇的近卫军</a> 2009-06-27 16:27 <a href="http://www.cppblog.com/golq/archive/2009/06/27/88644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>