+ -
当前位置:首页 → 问答吧 → C++的 static,大牛轻砸

C++的 static,大牛轻砸

时间:2010-06-28

来源:互联网

本帖最后由 xyfree 于 2010-06-28 18:05 编辑

C 里面 static 的用处太多,这里只谈 C++ 中比 C 增加的作用:在类或结构体中修饰对象属性和成员方法

通常我们声明类或结构体的时候,是因为我们抽象了一类数据的特征。
然后倒过头来,我们给这些特征起个名字(即类名),用来描述这一类对象。

这些对象通常都是两两不相关的,但有些时候,我确实希望他们相关。
例如以下的建模,static 的经典作用。

设计有一个动物类,并且希望统计动物的总数,怎样做最方便?
创建了一个动物的实体,就将数字增加一
  1. class Animal {
  2. private:
  3.     static unsigned int total_number;
  4. protected:

  5.     // 不允许建立Animal实例,因为是抽象的,但子类用得上。
  6.     Animal(void) {
  7.         ++total_number;
  8.     };

  9.     // 这个不是 virtual的,不然就失效了
  10.     ~Animal(void) {
  11.         -- total_number;
  12.     };

  13. public:
  14.     static unsigned int number(void) {
  15.         return total_number;
  16.     }
  17. };

  18. // 猫科动物,顺便也统计一下猫科动物的数量
  19. class Feline : public Animal {
  20. private:
  21.     static unsigned int feline_number;
  22. protected:

  23.     // 显式调用 超类 Animal的构造函数
  24.     Feline(void) : Animal() {
  25.         ++feline_number;
  26.     }

  27.     ~Feline(void) {
  28.         -- feline_number;
  29.     }

  30. public:
  31.     static unsigned int number(void) {
  32.         return feline_number;
  33.     }
  34. };

  35. // 犬科动物,顺便也统计一下犬科动物的数量
  36. class Canine: public Animal {
  37. private:
  38.     static unsigned int canine_number;
  39. protected:

  40.     // 显式调用 超类 Animal的构造函数
  41.     Canine(void) : Animal() {
  42.         ++canine_number;
  43.     }

  44.     ~Canine(void) {
  45.         -- canine_number;
  46.     }

  47. public:
  48.     static unsigned int number(void) {
  49.         return canine_number;
  50.     }
  51. };

  52. class Cat : public Feline {
  53. };

  54. class Lion : public Feline {
  55. };

  56. class Dog: public Canine {
  57. };

  58. int main(void) {

  59.     Cat cat;
  60.     Lion lion;
  61.     Tiger tiger;
  62.      Dog  groovy, jerry;

  63.      std::cout<<Animal::number()<<std::endl;
  64.      std::cout<<Feline::number()<<std::end;
  65.      std::cout<<Canine::number()<<std::endl;

  66. };
复制代码
从运行结果你应该可以知道

static 修饰的成员变量,无论有多少个对象,都只有一份

static 修饰的成员方法不会被继承,因为它不会被改写为 thiscall (带this参数的方法),
所以里面也不可以调用任何非static的成员函数,当然也不可以加const修饰

其实使用 static 修饰, 跟在C 里面添加了一个 全局变量、全局函数没什么区别
只是在C++之中,在不使用 命名空间的情况下,也可以将这些 “准全局变量”“准全局函数”的名字保护起来,不污染整个全局命名空间。
并且可以使用OO的封装特性,不允许其他代码随意修改或调用。

作者: xyfree   发布时间: 2010-06-28

顶!!!

作者: rain_fish   发布时间: 2010-06-28

lz 想说啥

作者: koolcoy   发布时间: 2010-06-28

回复 koolcoy


    本来还想说,Java C++ C# 什么的主流OO语言,static 在语言里面的这个用法其实是权宜之计。

    不过这个要说的东西太多了,加上本来这帖子就是为某些精通C但又不是很懂C++的人看的,就不废话那么多了(虽然还是很废话)

作者: xyfree   发布时间: 2010-06-28

...............

作者: ah13k   发布时间: 2010-06-28

回复 xyfree


    singleton pattern可能会用到static

作者: yangyuke   发布时间: 2010-06-28



QUOTE:
static unsigned int number(void) {
         return total_number;
}



请教一下楼主
这个static 究竟是修饰number还是unsigned

作者: pmerofc   发布时间: 2010-06-28



QUOTE:
回复  koolcoy
本来还想说,Java C++ C# 什么的主流OO语言,static 在语言里面的这个用法其实是权宜之计。
xyfree 发表于 2010-06-28 18:17




谁让这些狗屁的主流OO语言连free function都不支持。

class math {
static min
static max
static log
static floor

狗屁

作者: OwnWaterloo   发布时间: 2010-06-28

回复 OwnWaterloo


    C++支持的吧?
    可是即使支持free function,使用 static 依然是一个权宜之计。
    因为 static 这种东西,它的生命周期似乎是很长的,但实际上也应该可以由程序员来管理,
    但是很少语言有提供程序员这个能力,Java做得多一点点,提供一个 transient 关键字

作者: xyfree   发布时间: 2010-06-28

回复 xyfree

晕, C++被夹在中间……

作者: OwnWaterloo   发布时间: 2010-06-28