Pro visual c++/cli and .net 2.0 platform2 学习笔记(9第三章 面向对象的C++/CLI==2)

 

虚函数

重写overriding)虚函数有两种方式:隐式,显式

隐式

语法:virtual void Speak () override{}

阻止虚函数链:防止虚方法繁殖给他的后代。通常没有必要,不过可以这么做。语法:void Speak() new();也可以隐藏以后再开始一个新的虚方法 语法:virtual void Speak() new{};作者认为这两种都违反面向对象的程序设计原则。注意:纯虚函数不能被用hide

显式(命名的(名字可以相同,也可以不同))

语法:virtual void Yip () = Dog::Speak{}

它的一个好处是可以克服new的阻止,因为他可以override不仅仅是父类,而且可以是爷爷类,甚至是祖...爷爷类,多远都行。

语法:/*begin==================

ref class Tiger : public Cat

{

public:

virtual void Growl () = Animal::Speak//注意:Grow!=speak

{}

};

END=========*/

另一个更cool的好处是:从一个虚方法产生两个不同的虚方法序列。做法是:用同一个名字开始一个新虚序列(该虚序列已经被new封了),解释这个比较让人难懂。/*翻译就更难了*/ 代码却能很好的表述:

/*begin==================

ref class Animal

{

public:

virtual void Speak ()

{

Console::WriteLine("Animal is Mysteriously Silent");

}}

ref class Cat : public Animal

{

public:

virtual void Speak() new // 虚序列被阻止了(译者:包括cat自身)

{

Console::WriteLine("Cat says Meow");

}};

ref class Tiger : public Cat

{

public:

virtual void Speak() override = Animal::Speak //注意这里

{

Console::WriteLine("Tiger says Growl");

}};

END=========*/

函数重写

函数重载

不支持缺省参数,解决方法:参数要少,在函数内初始化。//不过这好像没解决根本问题

作者希望微软能恢复缺省参数,虽然他肯定微软取消缺省参数是有原因的。

操作符重载:c++/CLI必须是静态的,因此没有了隐含的this,因此也就多了一个参数。

另外要注意,c++的操作符重载也是被c++/CLI支持的(不过就不能支持多编程语言了)。另外在同一个ref类中不同对同一个操作符即用C++也用C++/CLI

C++/CLI中不能被重载的一些重要操作符:[],(),gcnew,new,delete

//p114重载++的例子很好

//p116注意:同时实现了x++++x

//p117注意:〉同时实现了 class,int)和(int,class

属性成员

主要是解决成员变量的访问问题,在或得get set的同时,简化了访问的形式,就象普通成员变量一样访问。(c++中用getset需要显式调用getset。)

trivial属性:语法property type PropertyName;//没有太大意义

Scalar属性:语法

property type PropertyName

{

type get() {};

void set (type value) {};

}

注:只有get就是只读属性,只有set就是只写属性,getset都有是可读写属性。

属性名不能和相应的成员变量名相同;但作者推荐(并非语法强制)成员变量第一个字符小写,属性名第一个字符大写。

set中通常检查传入的变量是否符合要求,并设置相应的成员变量。

属性的使用和普通成员变量相同。

静态属性:和静态成员变量相关联。

数组属性

语法:属性的类型为array类型

用法:用[]来访问

indexed属性

用法:用[]来访问,不过[]里面可以是任何类型(数组属性只能是0,1,2,3)。

语法:

property type PropertyName [ indexType1, ..., indexTypeN ]

{

type get(indexType1 index1, ..., indexTypeN indexN) {};

void set(indexType1 index1, ..., indexTypeN indexN, type value) {};

}

关键是getset里的实现://用到了集合类,也可以自己设计(如链表)。见例子3-12

缺省indexed属性

用法:用default代替属性名,可以直接用对象名[]访问而不用加属性名(本身也没有名字(如果说有也是default))。

对应内部一个集合类成员。

Number number;

number[1]

语法:property type default [type]{}

//总结:每种属性都应由一个对应的成员。

嵌套类:

//书中有一个图清楚地表明了嵌套类的访问权限。好图啊,一图顶万言。

类型转换

static_cast

static_cast最快也最危险//not verified也就是unsafe

dynamic_cast失败,返回nullptr

safe_cast,失败,抛出异常

//const_cast

抽象类

抽象类的构造函数:只能放在派生类的初始化列表中;应该protected(因为它必须被继承使用)。

必须有纯虚函数,abstract不必须(单更清楚,建议加上,尤其代码很多时)

因为它必须被继承使用,所以不能sealed,但可以实现一个虚方法并sealed//virtual void Method1() override sealed。前面讲虚方法时并没有介绍sealed

语法:ref class AbstractExClass abstract{}

接口

语法:interface class Interfacename

interface内部只能为public,函数不用virtual,=0

接口内可以定义属性,但不能有实现。

一个类可以同时继承一个类和多个接口,例如:ref class DerivedClass : public Base, public Interface1, public Interface2{}

另外:实现接口的方法时必须加上virtual,否则编译错误。

总结:

<skip>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值