C++ /CX在语法上的一些扩展
来源:互联网 发布:it团队管理经验 编辑:程序博客网 时间:2024/06/03 17:01
转载地址:http://www.devdiv.com/%E3%80%90windows8%E5%BC%80%E5%8F%91%E3%80%91%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BAC___CX-thread-128696-1-2.html
什么是C++ /CX? 首先要明白它跟C++ 0x/11以及C++ /CLR是完全不同的东西。C++ 0x/11是目前最新的C++标准库,而C++ /CX其实是微软在Win8开发平台下,对C++语言的一种扩展。C++ /CLR是微软为了C++能在.Net下运行,针对CLR,虽然也是对C++的扩展,但它编译后是托管于CLR的,属于Managed C++。而C++ /CX则属于Native C++,它不使用CLR也没有垃圾回收机制。虽然C++ /CX有些新语法特性是直接从/CLR借鉴过来的,但是从底层实现上来看,它们是完全不同的两种扩展。
本文会简单介绍C++ /CX在语法上的一些扩展。
1.值类型value和引用类型ref
value和ref都是用来定义class的,所以有如下的语法:
1
ref
class
Object{};
2
value
class
Object{};
两者有什么不同?其实引用类型ref类似于Java里面的引用概念,而值类型value就是我们通常理解的C++类型。那又为什么要增加这样的关键字来进行区分呢?原因是不管统一成ref类型还是value类型都有一定缺陷。
值类型value的话,在栈上分配空间,效率较高,但是它不支持多态,所以比如作为函数返回值使用时,有时会存在部分拷贝的问题。其实标准C++里面都是值类型value,别说有指针什么呢,指针本身不过是个整型的地址值,它还是值类型的,也别跟我说什么函数参数传递有传值和传址呢,即使传址,所传递的指针本身还是以值的形式传递的。
而引用类型ref,支持多态,但是它是在堆上分配空间,效率较低,而且会带来额外引用计数上的开销。
所以C++ /CX决定把两者区分开来,让开发者根据实际情况是选择。比如没必要支持多态的我们可以考虑使用value类型,比如希望交给系统管理引用计数的我们可以考虑使用ref类型。
2. public类
C++ /CX里有这样的定义:
1
public
ref
class
Object {};
2
public
value
class
Object {};
用public来定义类,作用其实显而易见,所有准备对外公开的类必须设为public,比如组件里对外公布的类,如果不定义为public的话,外部是访问不到指定类型的。另外Native C++类(标准C++里的类)不能被定义为public,只有ref和value类型的类才可以设定为public,所以下面的代码编译会报错:
1
public
class
Object {};
// compiler error
1. 标准C++方式的类不能被使用在public类的public属性成员中。
2. public ref类型类的public属性成员中,除非使用property,否则不能声明类成员变量。
3. public value类型的类的public属性成员中,不能声明类成员变量以外的成员,如函数等。
3. ^符号
C++ /CX中,就是用^来表示当前数据类型是ref引用类型。
比如有如下class:
1
ref
class
SomeObj {
2
public
:
3
void
SomeFunc();
4
};
那么在新建这个类对象时,由于是ref引用类型,所以会通过如下方式创建对象:
1
SomeObj^ obj = ref
new
SomeObj();
访问类具体成员对象时使用“->”
1
obj->SomeFunc();
^的变量代表它是引用类型的,系统会负责他们的引用计数,当引用计数为0时,它们会被销毁。
4. property
可以在public属性中用property关键字来公开类的成员变量,比如:
1
ref
class
SomeObj {
2
public
:
3
property
int
propertyX;
4
};
可能你会觉得上面的写法跟不加property貌似没有什么区别,在使用确实上是一样的,但是用property的方式其实是会去自动生成针对m_propX的默认get(),set()函数,类似下面这样:
1
ref
class
SomeObj {
2
public
:
3
property
int
propertyX{
4
int
get() {
return
mX; }
5
void
set(
int
x) { mX = x; };
6
}
7
private
:
8
int
mX;
9
};
那property关键字的使用到底有什么实际意义呢?
首先,如果是public定义的类,那么它的public属性中只能通过property才能定义成员变量,如下这样的定义编译会出错:
1
public
ref
class
SomeObj {
2
public
:
3
int
mX;
// compiler error
4
};
其次,通过property可以控制成员变量的访问权限,比如只读,可读可写等,如下代码就把propertyX设置为只读了:
1
ref
class
SomeObj {
2
public
:
3
property
int
propertyX{
4
int
get() {
return
mX; }
5
}
6
private
:
7
int
mX;
8
};
同时我们还可以自己定义成员变量的读操作或写操作,如下代码把写操作控制为只会被设置为非0的值:
01
ref
class
SomeObj {
02
public
:
03
property
int
propertyX{
04
int
get() {
return
mX; }
05
void
set(
int
x) {
06
if
(x != 0) mX = x;
07
};
08
}
09
private
:
10
int
mX;
11
};
5. 委托delegate和事件event
先看delegate的一个实例:
01
delegate
void
EventHandler(
int
x);
02
ref
class
WinRTObj sealed
03
{
04
public
:
05
WinRTObj() {
06
eHandler = ref
new
EventHandler([
this
](
int
x) {
07
this
->mX = x;
08
});
09
}
10
void
FireEvent(
int
x) {
11
eHandler(x);
12
}
13
EventHandler^ eHandler;
14
private
:
15
int
mX;
16
};
delegate声明的EventHandler其实功能就类似于函数指针,在WinRTObj类中我们定义了EventHandler^类型的成员变量,并在构造函数中初始化,new EventHandler时的参数是一个Lambda表达式的匿名函数,所以在FireEvent中调用eHandler(x)时,其实就会去运行这个匿名函数。
我们再把event应用到上面这个例子中,看看event有什么功能:
01
delegate
void
EventHandler(
int
x);
02
ref
class
WinRTObj sealed
03
{
04
public
:
05
WinRTObj() {
06
eHandler += ref
new
EventHandler([
this
](
int
x) {
07
this
->mX = x;
08
});
09
}
10
void
FireEvent(
int
x) {
11
eHandler(x);
12
}
13
event EventHandler^ eHandler;
14
private
:
15
int
mX;
16
};
上面的代码我们只是在声明eHandler时用了event关键字,同时在构造函数创建eHandler时,把"="改成了"+="。那么event增加了什么特性呢?从"+="可以看出,我们可以通过"+="向eHandler添加多个委托,如下所示:
01
WinRTObj() {
02
eHandler += ref
new
EventHandler([
this
](
int
x) {
03
this
->mX = x;
04
});
05
eHandler += ref
new
EventHandler([
this
](
int
x) {
06
// ......
07
});
08
eHandler::add(ref
new
EventHandler([
this
](
int
x) {
09
// ......
10
}));
11
auto temp = eHandler::add(ref
new
EventHandler([
this
](
int
x) {
12
13
// ......
14
}));
15
eHandler::
remove
(temp);
16
}
从上面的代码可以看出,除了用"+="来添加委托外,我们还可以用add方法,同时也可以用remove方法删除已经绑定的委托。
现在大家应该明白delegate结合event的具体作用了吧。
6. partial类
partial关键字也是用来修饰class,它可以让类可以再多个地方定义同一个类,在编译的时候会自动合并。比如:
01
partial ref
class
N
02
{
03
public
:
04
int
Method1();
05
static
int
sData1;
06
};
07
ref
class
N
08
{
09
public
:
10
void
Method2();
11
int
mData2;
12
};
有什么用呢?其实在实际开发的代码中应该很少会用到,之所以需要partial,是因为Metro UI的界面是用XAML画的,VS会把XAML传变为实际代码,因为这些UI代码跟本身开发的UI逻辑代码等是属于同一个类,所以XAML转变的那部分会被定义为partial,然后编译的时候会被自动合并。
好了,关于C++ /CX的特性就说这么多,其实这些以外/CX还有很多新特性,比如内置类型,C++模板,枚举,异常等方面都有一些新的扩展。还是那句话,本文只是个说明的引子,更全的资料参照MSDN吧。
- C++ /CX在语法上的一些扩展
- win32程序使用C++/CX语法
- 初学C语言时在语法和语义上容易犯的一些错误
- delphi的一些扩展语法
- C#与C++混合编程---C++/CX语法
- Ojbective-C的一些语法
- c的一些基本语法
- hal-c 在dsp 上应用的一些想法
- 在原有项目上新增加扩展应用的一些吐槽
- Java语法上的一些细节
- 从C到C++的第一步:了解C和C++在语法上的不同
- 深入浅出C++/CX
- C++/CX特性解读
- C++/CX 属性
- 是原生的但带反射的 C++/CX
- C#/list定义的一些扩展
- WinPhone8.1 C++/CX引用C#的DLL陷阱
- C语言在8051单片机上的扩展(interrupt、using关键字的用法)
- Linux 技巧
- 注册表的一些命令
- 小试Objc中的类
- emacs orgmode 简单文章编辑示例
- 【多线程】两种方式创建线程
- C++ /CX在语法上的一些扩展
- UML基本类图
- Linux shell3
- AJAX的POST和GET
- c语言的控制流
- 级联删除
- 排序 : 2 插入排序
- Mapreduce Strips算法 实现
- JavaSE学习 第十六章 线程