📄 00872.html
字号:
子类对象也是它们的父类对象的有效表示。例如,每一个<i>LinkPacket</i>对象都是一个完全合法的<i>Packet</i>对象。<br><br>一个<i>LinkedPacket</i>对象的句柄可以赋值到一个<i>Packet</i>变量: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00017.html" target="topic">11.14 super</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
<span style="color: #0000FF">super</span>关键字在一个继承类的内部使用,可以用来引用其父类的成员。当父类成员被继承类成员过载的时候就有必要使用<span style="color: #0000FF">super</span>关键字来访问负类的成员。 </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00018.html" target="topic">11.15 强制类型转换</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
将一个子类变量赋值给层次树中较高的类变量是合法的。将一个超类变量直接赋值给一个子类变量则是非法的。然而,如果超类句柄引用了指定子类的句柄,那么将一个超类句柄赋值给一个子类变量则是合法的。<br><br>为了检查赋值是否合法,需要使用动态强制类型转换函数<span style="color: #0000FF">$cast</span>(参见<a href="00386.html" target="topic">3.15节</a>)。<br><br><span style="color: #0000FF">$cast</span><span style="color: #800080">()</span>的语法如下: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00019.html" target="topic">11.16 串接构造器</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
一个子类在实例化的时候会调用类方法<span style="color: #0000FF">new</span><span style="color: #800080">()</span>。在函数中定义的任何代码执行之前,<span style="color: #0000FF">new</span><span style="color: #800080">()</span>执行的一个动作是调用其超类的<span style="color: #0000FF">new</span><span style="color: #800080">()</span>方法,并且会沿着继承树按这种方式一直向上调用。因此,所有的构造器都会按正确的顺序调用,它们都是起始于根基类并结束于当前的类。<br><br>如果超类的初始化方法需要参数,那么会有两种选择:一种选择是总是提供相同的参数,另外一种选择是使用super关键字。如果参数总是相同的,那么它们可以在被扩展的时候指定: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00020.html" target="topic">11.17 数据隐藏与封装</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
到目前为止,所有的类属性和方法都毫无限制地在类外可见。然而,我们有时希望通过隐藏类属性和类方法的名字来限制在类的外部访问类属性和类方法。这就使得其它程序员能够不依赖于一个特定的实现,而且它还防止仅对类内部有效的类属性被偶然地修改。当所有的数据都变成隐藏的(仅能被公共方法访问),代码的维护和测试都变得更加容易。<br><br>在SystemVerilog中,未被限定的类属性和方法是公共的,它们对访问对象名字的任何人都是有效的。<br><br>一个被标识成<span style="color: #0000FF">local</span>的成员仅对类内的方法有效。而且这些本地成员在子类内是不可见得。当然,访问本地类属性或方法的非本地方法可以被继承,并且作为子类的方法它可以正确地工作。<br><br>除了可以被继承以及对子类可见外,一个被标识成<span style="color: #0000FF">protected</span>的类属性或方法具有本地成员的所有特性。<br><br>注意:在类的内部,一个本地方法或类属性可以被引用,即使它处于一个不同的实例中。例如: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00021.html" target="topic">11.18 常量类属性</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
与任何其它SystemVerilog变量一样,类属性可以通过<span style="color: #0000FF">const</span>声明成只读的。然而,由于类属性是动态的对象,类属性允许两种形式的只读变量:全局常量和实例常量。<br><br>全局常量类属性是那些在声明中包含了初始值得常量类属性。它们与其它的const变量类似,也就是它们不能在除声明之外的其它地方赋值。 </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00022.html" target="topic">11.19 抽象类与虚拟方法</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
我们可以产生一组类,它们可以看作是来源于一个共用的基类。例如,一个类型为BasePacket的公用基类设置了一个包的初始结构,但这个结构并不完整,因此它永远也不会被实例化。然而从这个基类开始,我们可以派生许多子类,例如以太网包、令牌环包、GPSS包、卫星包。这些包的每一个可能看上去很相似,它们都需要相同的方法集合,但它们在内部的实现细节上则存在明显的不同。<br><br>一个基类设置了其子类的原型。由于设置基类的目的就不是为了实例化,所以可以将类指定成virtual以便使其变得抽象: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00024.html" target="topic">11.20 多态性:动态方法查找</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
多态性使得超类中的一个变量能够保存子类对象,并且能够直接从超类变量中引用这些子类的方法。考虑一个例子,假设<i>Packet</i>对象的基类<i>BasePacket</i>通过虚拟函数定义了通常由它的子类使用的所有公开方法(例如<i>send</i>、<i>receive</i>、<i>print</i>等)。这时,尽管<i>BasePacket</i>是抽象的,它仍然可以用来声明一个变量: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00025.html" target="topic">11.21 类范围解析操作符 ::</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
类范围操作符 <span style="color: #800080">::</span> 被用来指定在一个类作用范围内定义的一个标识符。它具有下列形式: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00026.html" target="topic">11.22 块外声明</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
如果能够将方法定义放在类声明体的外部,那将是很方便的。这个功能可以通过两个步骤完成。首先,在类声明体内声明方法的原型(无论它是任务还是函数)、任何限定符(<span style="color: #0000FF">local</span>、<span style="color: #0000FF">protected</span>或<span style="color: #0000FF">virtual</span>)、以及完整的参数说明加上<span style="color: #0000FF">extern</span>限定符。<span style="color: #0000FF">extern</span>限定符指示方法体(它的实现)在类声明的外部。接着,在类声明的外部声明完整的方法(与原型类似但没有限定符),并将这个方法绑定回它所属的类:使用一对冒号(<span style="color: #800080">::</span>)将方法名限定为类名字。 </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00027.html" target="topic">11.23 参数化的类</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
如果定义一个基本类,它的对象在实例化的时候可以具有不同的数组尺寸或数据类型,那么这种功能通常很有用。我们可以不必为每一个尺寸或类型编写相同的代码,并且可以为本质上不同并且不可互换的对象使用同一个说明(这与C++的类模板类似)。<br><br>普通的Verilog参数机制可以用来参数化一个类: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00028.html" target="topic">11.24 typedef类</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
有时一个类变量需要在类本身被声明之前声明。例如,如果两个类中的每一个类都需要另外一个类的句柄。在编译器处理第一个类的声明期间,编译器遇到了第二个类的引用,而这个引用是未定义的,因此编译器会将它标记为一个错误。<br><br>通过使用<span style="color: #0000FF">typedef</span>来为第二个类提供提前声明就可以解决这个问题: </div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00029.html" target="topic">11.25 类与结构体</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
SystemVerilog加入了面向对象的类结构。从表面上看,类与结构体似乎提供了等价的功能,似乎只需要其中的一个就足够了。然而,事实并非如此;类在下述四个基本方面与结构体是不同的:</p>
<ol class="Element630">
<li value="1" class="Element600">SystemVerilog结构体是严格的静态对象;它们或者在一个静态的存储位置(全局或模块的作用范围)或者在一个自动任务的堆栈中产生。相反,SystemVerilog对象(也就是类实例)则是动态的,它们的声明不会产生对象,产生对象是通过调用<span style="color: #0000FF">new</span>实现的。</li>
<li value="2" class="Element600">SystemVerilog结构体是类型兼容的,只要它们的位尺寸是相同的,因此拷贝具有不同的构成但尺寸相等的结构体是合法的。相反,SystemVerilog对象具有严格强类型。将一种类型的对象拷贝到另外一个类型的对象是不被允许的。</li>
<li value="3" class="Element600">SystemVerilog对象使用句柄实现,因此它提供了类似于C语言指针的功能。但SystemVerilog不允许为其它类型产生句柄,因此,与C语言不同的是,能够保证SystemVerilog句柄是安全的。</li>
<li value="4" class="Element600">SystemVerilog对象构成了面向对象数据抽象的基础,它提供了真正的多态性。类实例、抽象类、以及动态强制类型转换提供了强大的机制,它远远超过了结构体仅能提供的封装机制。</li>
</ol><p class="Element207">
</div></td></tr><tr>
<td class="Element202" valign="top" width="50%">
<div class="Element203">
<a href="00030.html" target="topic">11.26 内存管理</a> </div></td><td class="Element206" valign="top" width="50%">
<div class="Element207">
对象、字符串、动态数组、以及联合数组的内存是动态分配的。当创建对象的时候,SystemVerilog会分配更多的内存。当对象不再需要的时候,SystemVerilog自动地释放内存以便这些内存能够被重新使用。自动的内存管理系统是SystemVerilog的整体组成部分。如果没有自动的内存管理,SystemVerilog的多线程、重进入环境会增加许多导致用户出错的机会。一个手工的内存管理系统(就像C语言的<span style="color: #0000FF">malloc</span>和<span style="color: #0000FF">free</span>所提供的那样)是不够的。<br><br>例如,考虑下面的例子: </div></td></tr></table></div></div>
</div>
</div>
</div>
<a name="Links"></a><div class="Element14">
<a onclick="toggleVisibilityStored('链接');" class="a_Element14"><img src="sectionminus.png" border="0" alt="" title="" id="img链接">链接</a></div>
<div id="div链接">
<div class="Element11">
<div class="Element10">
<a href="00924.html" target="topic">主题</a></div>
</div>
</div>
</div>
<!-- End Page Content -->
<!-- Begin Page Footer -->
<hr width="98%" align="center" size="1" color="#CCCCCC" />
<table align="center" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr height="10">
<td></td>
</tr>
<tr align="center">
<td>
<script type="text/javascript"><!--
google_ad_client = "pub-5266859600380184";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel ="";
google_page_url = document.location;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</td>
</tr>
<tr height="15">
<td></td>
</tr>
<tr align="center">
<td>
<font size=2>除非特别声明,原文版权归作者所有,如有转摘请注明原作者以及译者(<a href="http://www.fpgatech.net/" target="_blank">FPGA技术网</a>)信息。<br />
如果您对本主题有何建议或意见,请登陆<a href="http://www.fpgatech.net/forum/forumdisplay.php?fid=18" target="_blank">FPGA开发者家园</a>提交,您的参与是我们前进的动力。</font>
<script language="javascript" type="text/javascript" src="http://js.users.51.la/195685.js"></script>
<noscript><a href="http://www.51.la/?195685" target="_blank"><img alt="我要啦免费统计" src="http://img.users.51.la/195685.asp" style="border:none" /></a></noscript>
</td>
</tr>
</tbody>
</table>
<!-- End Page Footer -->
</div>
</div>
<!-- End Client Area -->
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -