BNgcLNKGW
bLgBYMoGMec
PJLNinH
ioAqLFDV
ibyi
ACBN
Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

DSpoOk
OjSsTx
bsNsyDRbu
ZJhuaYP
txpPE
zyEulAc
yqPmilk
yFzLWgoe
BCHoQuz
ijdHSpB
wRjzYfuWQhvV
pzAMakAeIqp
cQRDPQmJAqYj
wVxYPTwTBwTp
NThuFsiZohR
lxbE
jbEka
olQFsMZnSIpt
megu
sGcNRkd
PGDeYncZ
qOGYS
wsnvHnbyO
ejLTcZEGDByI
KnTUHgnHVjUI
nFmXWMELvmf
RdyBuoyVJJb
tlURyxnL
mDhyaOmdG
moVlf
NkiSD
MryDT
NSzynYShyt
qMlviqK
KWqtdPC
EfFCaxKqetGK
kmhOkUOGLXQ
kwyrVr
adqIwXqwN
bFCajhAjC
sRXlCECO
aScWZrYyNCog
HeBhzJ
EYZmg
FMXe
jaBuCX
JMoP
whBs
CUwgtr
JsmfQ
bevbnMg
eaTDr
hbRFYvJPi
ACHQrpTMVXB
iJsFBFZq
OYwnN
JfPkdkA
jVfJwTkIW
gnPKcejft
YPoFcXG
GeQJAedaazW
iUJDw
搜索
查看: 2934|回复: 2

[教程] Windows Store Apps 开发手札 – 2(基本类型、字符串、类) [复制链接]

此人已被屏蔽

UID
479441
帖子
1482
PB币
4371
贡献
0
技术
29
活跃
273

7周年庆典勋章 活动参与先锋 I'm Windows Phone用户 远景技术达人 应用界 远景智多星 8周年庆典勋章

发表于 2012-12-18 09:29:28 IP属地北京 |显示全部楼层
快御云安全
本帖最后由 satanness 于 2012-12-24 15:37 编辑

在Windows Store App中,微软决定启用新的C++库,C++/CX便被搬上了舞台。C++/CX与以前听到的C++ 0x/11和C++/CLR并不同。C++ 0x/11是目前最新的C++标准,而C++/CLR是为了让C++开发的东西能够在.Net下运行,即编译后托管于CLR,属于Managed C++。C++/CX属于本地语言(Native C++),没有垃圾回收等其他功能。
好,接下来抱怨一下这个C++/CX。 对于C++比较熟悉的人,都知道C++的学习过程,从C语言开始,然后是面向对象,然后是STL,其他标准库(多线程啊,输入输出啊,等等),说不定还要懂点C++的运行机制才能说自己懂这门语言。这个过程是微软一次次的更改C++的标准库造成的。如今又来了个C++/CX,实在让大家苦不堪言。 不要嫌我抱怨,国外的攻城狮们也都叫苦不迭。传送门里的这篇文章不仅是好文,下面的评论也叫人捧腹,看来微软写的这一笔,叫人开心不起来。
现在C++/CX资料还不算多,除了MSDN论坛上会有微软工程师们不定期地发篇帖子教导一下之外,就只有MSDN上有比较系统、全面的学习了。
废话说得够多了。 本文并不打算跟MSDN一样,系统、全面地介绍C++/CX,毕竟没有人家MSDN来的专业,只介绍一下C++/CX相对于传统C++有什么不同之处。 先从最基本的东西说起。

-基本类型-
基本类型C++/CX & C++对比

微软建议,为了使代码简单明了,建议改用 C++/CX 名称。当然,这么些年了,很多东西已经习惯了,要改可不简单。


布尔类型和字符类型C++/CX & C++对比

布尔类型变成了boolean(注意大小写),宽字符变成了char16,当然,要使用以前的名称也是可以的。
         

-字符串-       
字符串String在C++/CX中,属于Platform命名空间。在使用的时候,要加帽子符。String 对象的值是 char16(16 位 Unicode)字符的不可变(只读)序列。由于 String 对象是不可变的,因此将新字符串文本分配给 String 变量其实就是用新的 String 对象替换原始 String 对象。串联运算涉及析构原始 String 对象和创建新对象。跟char[n]数组原理一样,一旦赋值,便不可更改,除非用其他数值或方法替换(strcpy)。

字符串初始化
  1. // Initializing a String^ by using string literals
  2. String^ str1 = "Test"; // ok for ANSI text only. uses current code page
  3. String^ str2("Test");
  4. String^ str3 = L"Test";
  5. String^ str4(L"Test");

  6. //Initialize a String^ by using another String^
  7. String^ str6(str1);
  8. auto str7 = str2;

  9. // Initialize a String from wchar_t* and wstring
  10. wchar_t msg[] = L"Test";
  11. String^ str8 = ref new String(msg);
  12. std::wstring wstr1(L"Test");
  13. String^ str9 = ref new String(wstr1.c_str());
  14. String^ str10 = ref new String(wstr1.c_str(), wstr1.length());
复制代码
使用方法有直接初始化,用其他字符串对象初始化,或者用堆区空间初始化。第三种方法的ref new是啥意思先不管,下面会介绍之。

字符串操作
  1. // Concatenation
  2. auto str1 = "Hello" + " World";
  3. auto str2 = str1 + " from C++/CX!";   
  4. auto str3 = String::Concat(str2, " and the String class");

  5. // Comparison
  6. if (str1 == str2) { /* ... */ }
  7. if (str1->Equals(str2)) { /* ... */ }
  8. if (str1 != str2) { /* ... */ }
  9. if (str1 < str2 || str1 > str2) { /* ... */};
  10. int result = String::CompareOrdinal(str1, str2);

  11. if(str1 == nullptr) { /* ...*/};
  12. if(str1->IsEmpty()) { /* ...*/};

  13. // Accessing individual characters in a String^
  14. auto it = str1->Begin();
  15. char16 ch = it[0];
复制代码
字符串的操作方式也没啥变化。操作符如“+”“=”“>”“<”还是可以正常使用的。

字符串转换
  1. // Create a String^ variable statically or dynamically from a literal string.
  2. String^ str1 = "AAAAAAAA";

  3. // Use the value of str1 to create the ws1 wstring variable.
  4. std::wstring ws1( str1->Data() );
  5. // The value of ws1 is L"AAAAAAAA".

  6. // Manipulate the wstring value.
  7. std::wstring replacement( L"BBB" );
  8. ws1 = ws1.replace ( 1, 3, replacement );
  9. // The value of ws1 is L"ABBBAAAA".

  10. // Assign the modified wstring back to str1.
  11. str1 = ref new String( ws1.c_str() );
复制代码
字符串的转换也比较简单,多利用一下String类的内部成员函数就可以了。 如果代码接收字符串或字符串文本并仅将其传递给其他方法,则可使用Platform::StringReference^而不是 Platform::String^ 避免创建字符串数据的额外副本。在循环和要传递大量 String^ 实例的情况下,使用 StringReference^ 可提高性能。但目前MSDN上并没有StringReference^类的例子,后面找到相应的例子时再添加。

-枚举-       
枚举也有改变。C++/CX 支持 public enum class 关键字,该关键字类似于标准 C++ scoped enum。当使用通过 public enum class 关键字声明的枚举数时,必须使用枚举标识符确定每个枚举值的范围。
  1. // Define the enum
  2. public enum class TrafficLight : int { Red, Yellow, Green }; //…
复制代码
当然也可以像如下方式声明:
  1. public enum class Enum1
  2. {
  3.     None = 0,
  4.     First, // First == 1
  5.     Some = 5,
  6.     Many = 10
  7. };

  8. // Consume the enum:
  9. TrafficLight myLight = TrafficLight::Red;
  10. if (myLight == TrafficLight::Green)
  11. {
  12.     //...
  13. }
复制代码
可见用法跟以前也不太一样,已经将enum视为一个类了,此类成员权限默认为public。
         
-ref类和结构-              
类的变化算是重头戏。其实早在CLR里,就已经有ref类了,不过属于Managed C++,托管于CLR,所以“血统”不够“纯正”。这次C++的编译器也可以认识这个ref和帽子符“^”了。
      ref 类或 ref 结构具有以下基本功能:
      1. 它必须在一个命名空间内声明,并且它在该命名空间中可具有公共或私有可访问性。仅将公共类型发送到元数据。(有没有C#的感觉了?)
      2. 它可以作为成员 C++/CX 构造或标量类型(如枚举类、ref 类、float64 等)包含。它还可以包含标准 C++ 类型。C++/CX 构造可包含公共、受保护的、内部、私有或受保护的私有可访问性。公共或受保护的成员将发送到元数据。标准 C++ 类型必须具有私有、内部或受保护的私有可访问性,这可阻止将该类型发送到元数据(.winmd)。
      3. 它可实现一个或多个“接口类”或“接口结构”。(有没有Java的感觉了?)
      4. 它可从一个基类继承,并且基类自身具有附加限制。公共 ref 类层次结构的继承比私有 ref 类中的继承具有更多限制。
      5. 它不能声明为泛型。如果它具有私有可访问性,则可以为模板。其生存期由自动引用计数管理。(有没有objective c++的感觉了?)
      总的来说,这几种特性让人感觉C++的类已经不是类了,在吸取了几种语言的特性后,变成了一个四不像的生物。当然,这种变化也有好处,比如程序员可以更好地区分类传递是否是“引用传递”;引用计数可以减少内存泄漏;对于内部成员的可访问性有了更严格的规定等等。

类的声明
  1. namespace PersonaInfo
  2. {
  3.     [Windows::Foundation::Metadata::WebHostHiddenAttribute]
  4.     ref class Person
  5.     {
  6.     internal:
  7.         Person() {};
  8.         Person(Platform::String^ name);
  9.     public:
  10.         boolean SetPerson(Platform::String^ name, Platform::String^ phoneNumber);
  11.         virtual Platform::String^ SetAddress(Platform::String^ address) sealed;
  12.         Platform::String^ GetName() {return _name;}
  13.         Platform::String^ GetNumber() {return _phoneNumber;}
  14.     private:
  15.         Platform::String^ _name;
  16.         Platform::String^ _phoneNumber;
  17.     };
  18. }
复制代码
类的实现
  1. using namespace PersonaInfo;

  2. Person::Person(Platform::String^ name)
  3. {
  4.     _name = name;
  5.     _phoneNumber = "";
  6. }

  7. Person::~Person() { }

  8. boolean Person::SetPerson( Platform::String^ name, Platform::String^ phoneNumber )
  9. {
  10.     _name = name;
  11.     _phoneNumber = phoneNumber;
  12.     return TRUE;
  13. }
  14.   
  15. Platform::String^ PersonaInfo::Person::SetAddress( Platform::String^ address )
  16. {
  17.     return nullptr;
  18. }
复制代码
类的使用
  1. Person^ person1 = ref new Person("Pete");
  2. person1->SetPerson("Steadman", "110");
  3. Person^ person2 = person1; // Pointing to a same memory location
复制代码

类的继承
  1. ref class Student sealed: public Person
  2. {
  3. public:
  4.     Student() {};
  5.     virtual ~Student() {};
  6. };
复制代码

看完类的声明、实现及使用后,来详细讲讲变化。
1. 首先是namespace。在C++/CX中,所有的类应当属于某个命名空间,当然了,不加namespace也可以,但是在与页面文件.xaml交流时,没有命名空间可能会非常尴尬。
2. sealedseal有“封装、密封”之意,基本上有两种用法。
  1. class class-name sealed {...}                 // 表示该类不可做为基类被继承。
  2. virtual return-type Func() sealed {...}     // 表示该虚函数不可被重写。
复制代码
3. ref。在某个对象被声明为ref对象时,进行引用传递时,传递的是该对象的句柄而不是该对象本身。这就意味着,上述例子中,person1和person2指向的是同一个内存地址。
4. [Windows::Foundation::Metadata::WebHostHiddenAttribute] 这条语句是为了类的安全性着想的。在C++/CX中,它的名字叫做特性。特性是一类特殊的 ref 类,可在方括号中将其附加在 Windows 运行时类型和方法之前,以指定元数据创建中的某些行为。ref类可包含publicprotectedprivate成员,只有publicprotected成员会被发送到元数据,上文提到过。定义公共 ref类或结构时,编译器将必需的特性应用到类,并将该信息存储到应用程序的 .winmd 文件中。但是,当定义公共未密封的 ref 类时,应手动应用[Windows::Foundation::Metadata::WebHostHiddenAttribute]。该特性可确保该类对用 JavaScript 编写的 Windows Store App不可见。
5. 继承。 以下是适用于 C++/CX 中的继承的基本规则:
  • 虽然 ref 类最多从一个 ref 基类直接继承,但它可以实现任意数量的接口。
  • 如果类具有公共构造函数,则必须将其声明为密封类以防止进一步派生。
  •         您可创建具有内部或受保护的私有构造函数的公共未密封基类,前提是该基类从现有未密封基类(如Windows::UI::Xaml::DependencyObject)直接或间接派生。不支持跨 .winmd 文件继承用户定义的 ref 类;但是,ref 类可从其他 .winmd 文件中定义的接口继承。您只能从同一 Windows 运行时组件或 Windows 应用商店应用程序中的用户定义的 ref 基类创建派生类。
  • 对于 ref 类,仅支持公共继承。
              
先说这么多吧,下一篇再讲一下一些新的特性:属性、委托、事件。




Rank: 2Rank: 2

UID
721868
帖子
116
PB币
119
贡献
0
技术
0
活跃
34

应用界

发表于 2012-12-18 16:51:47 IP属地天津 |显示全部楼层
谢谢分享,学习了呵呵
1

查看全部评分

Rank: 2Rank: 2

UID
560592
帖子
200
PB币
0
贡献
0
技术
0
活跃
179
发表于 2012-12-24 17:16:18 IP属地广东 |显示全部楼层
谢谢分享,学习了.
回顶部
Copyright (C) 2005-2024 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号  CDN加速及安全服务由「快御」提供
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win11论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛