C++与C#对比学习:让对象变得像常量

[来源] 达内    [编辑] 达内   [时间]2012-10-12

如果不希望用户修改字段.就把字段全部设为private的.然后用属性提供个接口.只有读的权限,不能修改.只有构造函数能赋值一次.那你可能会问其他成员函数会修改啊

  我们知道如果不希望改变某个变量的值就用const修饰它,让它变为常量.基本类型和指针类型都能用const来修饰.数组也可以用const来修饰.

  那你自然要问我们把class实例化成一个对象后,如果不希望修改对象中的成员变量,让对象变得像个常量一样该咋整呢?

  你首先自然会想到把类中所有的成员变量都用const修饰不就得了.其实这确实是个办法拉,但是如果我们只是想某个类的一个实例对象弄得像常量啊.你这样用const整就真成了常量了,所有类的实例都只能当常量来处理了.这显然不行拉.

  其实很简单,我们只要实例化类时加个const修饰下就OK,但是由于类不是个简单的类型.所以还涉及到一些特殊的操作.还是举个简单的例子看下.

  class MyClass

  {

  public:

  int age;

  string name;

  MyClass(int num,string str)

  {

  age = num;

  name = str;

  }

  void Test() { Print(); }

  void Print() const

  {

  stout<

  }

  ~MyClass(void);

  };

  const MyClass my(110,"arwen"); //实例化类时用const修饰.

  my.age = 911; //这样会出错,既然用const修饰了肯定就变得像常量一样,不能改变成员变量的值了.

  my.Print(); //正确执行

  (); //出错了

  为啥调用()时会出错呢? 这就是特殊的地方了.当用const修饰一个对象后,此对象就只能调用const修饰的函数了(const必须放到函数变后面).而一般的函数是不能被调用了.

  为啥这样其实很简单,出于一致性考虑.既然不让直接修改成员变量了.那任何潜在的有可能修改成员变量的操作都就禁止.因为一般函数中有可能会修改了成员变量值.所以干脆禁止调用.

  函数后面加个const是代表啥意思呢.它是代表在此函数中不能修改成员变量的值.例如

  void Print() const { age = 456;} //这样会出错.当然你如果在函数中修改其他不是成员变量的值就没问题.

  const修饰的函数中如果有调用到其他函数,那被调用的函数也只能是后面被const修饰的.当然一般函数调用const修饰的函数是没啥限制的.

  所以通过当用const修饰对象后

  1.不能像my.age = 911这样直修改成员变量

  2.对象只能调用被const修饰的函数

  3.被const修饰的函数中不能修改成员变量,且它也只能调用其他也被const修饰的函数.

  通过这三点确保了成员函数在任何情况下都不会被修改.用构造函数赋值后就一直不变.

  上面说到的用const修饰函数也可以单独用,不一定和const修饰对象配合用.单独用的话约定也是一样,函数中不能修改成员变量

  上面说的是在C++中,那在C#中呢?

  首先C#中一般把成员变量叫作字段.跟C++不同,C#中可以直接给字段赋值的.所以用const修饰类中的字段,然后赋值是没问题的.但显然我们很多时候是希望用构造函数来赋值的.那咋整呢?也像C++一样用个const修饰下就OK了吗.那不行.因为用const修饰引用类型时只能给赋值为null,那等于说那对象没任何用处了.当然C#自然有其他操作可以达到类似的效果.那就是通过属性加权限修饰符.

  class MyClass

  {

  private int age;

  private string name;

  public int Age {

  get{return age;}

  }

  public int Name {

  get{return name;}

  }

  MyClass(int num,string str)

  {

  age = num;

  name = str;

  }

  }

  如果不希望用户修改字段.就把字段全部设为private的.然后用属性提供个接口.只有读的权限,不能修改.只有构造函数能赋值一次.那你可能会问其他成员函数会修改啊?

  这就需要遵守一个约定了,就是类中其他函数别直接去用字段,也只是去用属性Age,Name.当然这只是推荐的作法,如果你实在想去直接用字段,去修改了.那就没办法了啊.

  反正C#中使用了属性,推荐的作法就是在成员函数中直接用属性,别直接用字段了.

  另外还有个办法就是用readonly修饰字段,这样就只能读不能修改了.达内

资源下载