zoukankan      html  css  js  c++  java
  • c++中的静态成员

    引言

    有时候需要类的一些成员与类本身相关联,而不是与类的每个对象相关联。比如类的所有对象都要共享的变量,这个时候我们就要用到类的静态成员

    声明类的静态成员

    声明静态成员的方法是使用static关键字。

    static成员可以是public也可以是private的。

    例如,定义一个类表示银行的账户记录:

    class Account{ public: //其他非静态函数及数据成员 //静态函数 static double get_rate(){ return interestRate; } static void set_rate(double r){ interestRate = r; } private: static double interestRate;//该类的所有对象公用同一个利率 //其他static private函数 //其他非static 函数及数据成员 };

    Note:

    • 类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。
    • 静态成员函数不与任何对象绑定到一起,不能在静态成员函数中使用this指针。静态成员函数不能被声明为const。

    使用类的静态成员

    使用作用域运算符::直接访问静态成员。

    double r; r = Account::get_rate();

    虽然静态成员不属于类的任何对象,但仍然可以通过类的对象访问静态成员。

    Account ac1; Account *ac2 = &ac1; double r = ac1.get_rate(); r = ac2->get_rate();

    成员函数可以直接使用静态成员,不需要作用域运算符。

    定义静态成员

    定义静态成员函数

    类的静态成员函数既可以定义在类的外部也可以定义在类的内部(注意定义和声明的区别)。

    当在类的外部定义静态成员函数时,不能使用static关键字,static关键字只在类内部该静态成员函数的声明处使用。否则重复。

    当在类的外部定义静态成员函数时,必须指明该函数所属的类,如:

    class Account{ public: //其他非静态函数及数据成员 //静态成员函数 static double get_rate(){ return interestRate; } static void set_rate(double r){ interestRate = r; } static void print();//静态成员函数声明 private: static double interestRate;//该类的所有对象公用同一个利率 //其他static private函数 //其他非static 函数及数据成员 }; //定义静态函数时不需要使用static关键字,否则重复。另外指明该函数所属的类。 void Account::print(){ //要完成的工作 }

    定义静态数据成员

    因为静态数据成员不属于类的任何一个对象,所以他们并不是在创建类的对象的时候被定义的。不能在类的内部初始化静态数据成员,必须在类的外部定义和初始化每个静态数据成员。

    double Account::interestRate = initRate();//不用static关键字

    静态数据成员的类内初始化

    前面提到,类的静态数据成员不应该在类的内部被初始化。但若静态数据成员同时还是constexpr类型,则可以在类内初始化。

    即使一个常量静态成员在类内被初始化了,通常也应该在类的外部定义一下该成员,但类外定义使不能再指定初始值,因为在类内已经提供了初始值。

    静态数据成员的特殊应用场景

    1. 静态成员独立于任何对象,因此,静态数据成员的类型可以是他所属的类类型,非静态数据成员只能声明为他所属的类的指针或引用。
      例如:
    class Person{ public: //... private: static Person p; //正确,静态数据成员可以是不完全类型 Person *p1; //正确:指针成员和引用可以是不完全类型 Person &p2 //正确 Person p3; //错误:数据成员必须是完全类型。 };//在此之前,class Person之后,Person类都是不完全类型,因只声明完但还没有定义完
    1. 可以使用静态成员作为默认实参
    class Screen{ public: Screen& clear(char = bkground); private: static const char bkground; }

    非静态数据成员不能作为默认实参,因为非静态数据成员属于对象,对象的值是在运行时确定的,但默认参数却是在编译时确定的,也就是说,默认参数确定时还没有真正的对象被创建,因此不能用非静态数据成员作为默认参数,否则引发错误。


    声明:
    c++ Basic是对《C++ Primer 第五版》的个人总结与疑难解释。
    如果想要深入了解更多,请支持正版。

  • 相关阅读:
    asp.net获取服务端和客户端信息
    ASP.NET 中JSON 的序列化和反序列化
    Asp.net TextBox常规输入验证
    ADO.NET中的五个主要对象
    .Net一般处理程序来实现用户名的验证
    .net获取当前网址url(各种参数值)
    hdu-1941 Find the Shortest Common Superstring
    字典树的动态与静态模板
    模板 Dijkstra+链式前向星+堆优化(非原创)
    基础深搜小结
  • 原文地址:https://www.cnblogs.com/wl-blog/p/15038616.html
Copyright © 2011-2022 走看看