当前位置:编程学习 > C/C++ >>

C++ VS C#(13):隐藏基类方法,部分类定义

//=====================================================================
//TITLE:
//    C++ VS C#(12):函数的重载,类成员的static修饰,属性
//AUTHOR:
//    norains
//DATE:
//    Monday  04-April-2011
//Environment:
//    Visual Studio 2010
//    Visual Studio 2005
//=====================================================================

1. 函数的重载

    在C++中,对象函数的重载只有一个原则,就是派生类和基类的函数名必须相同,除此以外,并无更多的约束,如:

   class CBase
   {
   public:
    virtual int Add(){};
   };
  
   class CDerived:
    public CBase
   {
   public:
    virtual int Add(){};
   };
  
    函数前的virtual只是告诉编译器,当用基类指针指向派生类对象时,调用的应该是派生类的Add函数;而如果没有virtual,那么在相同的情形之下,调用的则是基类本身的Add。但不管有无virtual,编译器都不会作出任何提示或警告。
  
    相对于C++而言,C#在这方面就智能一点。如果基类没有采用virtual关键字,并且派生类也没有采用override,那么编译器会有类似的警告:
   warning CS0114: Function.CDerived.Add() hides inherited member Function.CBase.Add(). To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
  
    不要小看这个不起眼的警告,也许在不少场合能帮上大忙。比如基类是由同事写的,并且其代码需要调用到派生类的某个重载函数,而你也确实重载了;但在随后的工作中,同事觉得这函数名不好看或什么杂七杂八的理由,更改了函数名,那么灾难就发生了,你重载的函数永远无法调用!如果有了这么一个警告,说不定类似的情形还能够避免。
  
    C#对于函数的修饰符,比C++多了三个,其功能列表如下:

修饰符
 说明
 
virtual
 方法可以重写
 
abstract
 方法必须在非抽象类的派生类中重写
 
override
 重写了基类的一个方法
 
extern
 方法定义在其它地方
 


2. 类成员的static修饰

    如果将static在class中使用,那么C++和C#有个非常明显的区别:在C#里,static修饰过的函数或变量,不能够通过对象来访问,而必须使用类来访问;而在C++中,则无此限制。
  
    我们来看看这个C++代码,注意代码中的注释:
   class CBase
   {
    public static int iVal;
   };
  
   int CBase::iVal = 0; //初始化static变量
  
   int _tmain(int argc, _TCHAR* argv[])
   {
    int iVal = 0;
   iVal = CBase.iVal;//通过类来访问
  
    CBase myObj;
    iVal = myObj.iVal;//通过对象来访问
  
    return 0;
   }
  
    但对于C#来说,情形确实大为不同,如下代码所示:
   class CBase
   {
       public static int iVal = 0;
   };
  
   static void Main(string[] args)
   {
       int iVal = 0;
  
       CBase myObj = new CBase();
       iVal = myObj.iVal; //该代码出错,因为static成员不能通过对象来访问
  
       iVal = CBase.iVal; //只能通过类来访问static成员
   }
  
    个人更喜欢C++的方式,因为类本来就是一个抽象的层次,对象是具体化的阶段,类可以访问的话,那么对象也应该可以访问,毕竟static是所有对象所共有的,通过对象不能访问static成员,无论如何也觉得情理不通。
  
    关于static还有一个区别,细心的朋友可能发现了,C++中的static变量声明是无法直接初始化的,而必须在.cpp中进行;至于C#,本来就没有头文件的存在,所以也无所谓外部定义,直接赋值即可。这点上,C#做的更好些。

  
  
  
3. 属性

    属性这玩意就没啥差异可说,当然并不是C++和C#是一样的,而是因为C++根本就没这东西,是C#所独有的。因为C++程序员可能对此不明白,所以特意提一下。
  
    所谓的属性,就是采用get和set的代码块,是作用于成员变量的,并且只有当操作符为"="时有作用。估计这样说,谁都会头疼,我们还是来看看实际的代码,如下所示:
   class CBase
   {
       private int iInternal = 0;
       public int iVal
       {
           get
           {
       //返回iInternal变量的数值
               return iInternal;
           }
  
           set
           {
       //设置iInternal的数值
               iInternal = value;
           }
       }
   };
  
  
   CBase myObj = new CBase();
   int iVal = myObj.iVal; //调用iVal 变量的get方法
   myObj.iVal = 5; //调用iVal 变量的set方法
   


    以一种不恰当的比喻说明,get和set就像是针对某个变量重载其"="操作符。C#属性的方式,打破了C++的一个信条:成员变量都应该声明为private,对其的存储尽可能使用函数的方式。当然,C#的所谓打破,其实也是形式上的打破,本质上其实也是遵循该信仰:如果直接通过对象来访问成员变量,当其赋值或获取不符合要求,就用get和set改变其行为。对于C++的程序员来说,可能唯一碍眼的仅仅是myObj.iVal这样的形式而已。

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,