C++回顾之成员函数重载、类与结构体、this指针

[复制链接]

1234

主题

-8

回帖

216

积分

游客

积分
216
a420995601 发表于 2018-12-23 03:01:26 | 显示全部楼层 |阅读模式
  C++回顾之成员函数重载、类与结构体、this指针
  前一篇文章中说到,内联成员函数的定义有两种方式,一种是在类体内部直接定义,第二种是在类体外定义。下面是代码:
  第一种定义方式:
  class Test
  {
  public:
  void add(int a, int b) //类体中直接定义时为内联函数。
  {
  return a+b;
  }
  };
  第二种定义方式为:
  inline Test::add(int a, int b) //在类体外定义
  {
  return a+b;
  }
  内联函数的目的主要是为了提高程序执行的效率,编译器在编译的时候会将代码直接嵌入到调用的地方,从而减少了函数调用的开销,如果不用内联函数,直接嵌入代码,则代码体积将增大,这实际上是以空间换取时间的策略。所以内联函数的代码必须短小,内联函数对编译器而言仅仅是一个提示,另外,如果函数中含有switch for 等语句,则编译器不会将其解读为内联。
  下面讲讲成员函数的重载 捕鱼游戏 星力捕鱼
  成员函数的重载是有条件的,首先必须具有相同的作用域,且参数不同(可以是参数类型不同,参数个数不同,参数顺序不同),函数名相同。这样的成员函数才构成重载。下面是重载的例子:
  class Test
  {
  public:
  void Init();
  void Init(int x);
  void Init(int x, int y);
  void Init(int x, int y, int z);
  //void Init(int x=0, int y= 0, int z= 0 ); //与void Init();函数产生了二义性,编译器无法区分
  };
  在上面这个例子中,定义了多个Init函数,由于他们的参数不同,所以构成重载,但是成员函数的重载需要注意的是,对于带有缺省值参数的成员函数的重载需要避免二义性,如上述代码中的注释行。它与不带参数的成员函数Init()就产生了二义性,编译器对此无法区分,因此会报错。
  类与结构体(struct 与 class)
  在C中的结构体struct其实与C++中的class有点类似的,它们都可以将各种数据结构与方法封闭在一个容器中。唯一的区别在于:在未指定访问权限时,struct默认是public的,而class默认是private的。如下:
  class Test
  {
  int x; //actually x is private.
  };
  struct Test
  {
  int x; //x is public
  };
  在class中可以定义函数,其实在C++中的struct内也可以定义函数,只不过他们的访问权限均为public的,如果class内定义的所有数据成员与成员函数均为public,则与struct定义没有任何区别。下面这段代码非常简单,可以看出二者的区别。
  struct Test2
  {
  int x_;
  int y_;
  int z_;
  void Init(int x, int y, int z)
  {
  x_ = x;
  y_ = y;
  z_ = z;
  }
  };
  class Test3
  {
  int x_;
  int y_;
  int z_;
  void Init(int x, int y, int z )
  {
  x_ = x;
  y_ = y;
  z_ = z;
  }
  };
  int main()
  {
  Test2 t; //在C++中,struct也是一个类,不需要加上struct
  t.Init(10,20,30);
  Test2 t2 = {10,20,30}; //C中结构体的初始化,这是允许的
  Test3 t3;
  t3.Init(10,20,30);//Error,Init在t3中是private的,外部无法直接访问
  Test3 t4 = {10,20,30}; //Error,在class中,数据成员为private,不能像struct那样初始化。
  }
  关于this指针
  为了搞清this指针,需要了解一个背景:在C++中,成员函数的代码对所有对象而言是共享的,而每个对象的数据成员空间各自独立,那么当每个对象都调用成员函数时,成员函数如何区别它应该操作哪一个对象的数据呢?换句话说,成员函数怎么知道它要操作的是调用它的对象的数据成员?这主要是C++编译器来完成,C++编译器在每次成员函数调用时,在第一个参数会增加一个对象的指针,以告诉成员函数它要操作的是哪个对象的数据。编译器传递的这个指针是不可见的,是隐含的。
  我们程序代码中调用成员函数是这样的:
  Test t1;
  t1.Init(10,20,30);
  而编译器处理后,是这样的:
  Test t1;
  t1.Init(&t1, 10, 20, 30);
  这个被编译器传递进去的指针就是this指针了,这样在成员函数代码被执行时就指向了t1的数据成员。当然,我们在成员函数定义时可以将这个this指针省略。

你喜欢看
  • python如何操作Sql Server 2008

      python如何操作Sql Server 2008   最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开 ...

  • linux内核如何管理进程

      linux内核如何管理进程   “进程”有诸多的定义,在许多的教材资料上,其定义是一个程序的执行实例, ...