《C++程序设计教程》——C++类中的static和const

摘自:《C++程序设计教程》——传智播客

2.4.1 用static修饰数据成员

● 静态数据位于数据段上,因此它们的生命周期从编译阶段开始,到程序运行结束才终止。
● 对于静态数据成员,若其被声明具有public属性,则其可以通过对象在类外完成访问,也可以通过类名直接对它进行访问。
● 若相对静态数据成员进行初始化,需要在类外通过“类名::静态数据成员 = 初值”的方法初始化。
● 静态数据成员是多个对象的共享数据。

//定义Student类
class Student                                    
{
public:                 
    Student();
    ~Student();
    //静态数据成员
    static int s_nTotalNum;  
private:
    char m_gName[20];
    int m_nID;
};
//类外对静态数据成员初始化
int Student::s_nTotalNum = 0;            

2.4.2 用const修饰数据成员

● 常数据成员必须进行初始化并且不能被更新。对常数据成员进行初始化只能通过初始化表完成,不能在构造函数内部赋值。

class Circle                                         
{
public:
    //声明构造函数
    Circle(double con_radius);                    
private:
    //常数据成员,描述圆周率                             
    const double PI;                                
};
//定义构造函数,常数据成员通过初始化表初始化
Circle::Circle(double con_radius) :PI(3.14)
{   
}

2.5.1 静态成员函数

● C++中用于操作静态数据成员的函数可以定义为静态成员函数。
● 静态成员函数可以通过“对象.静态成员函数名()”的形式完成调用,也可以无需定义对象,访问方式采用“类名::函数调用”。
● 通常静态成员函数访问静态数据成员,也可以访问其他静态成员函数。但是,若静态成员函数想访问非静态数据成员时,必须通过参数传递的方式得到数据名,然后在静态成员函数中通过函数名访问非静态成员。

#include <iostream>
#include <string>
using namespace std;

class Student                                         //定义Student类
{
public:
    Student(string con_name, int con_id);
    ~Student();
    //静态成员函数get_totalnum(),访问静态数据成员
    string get_stdname();
    //静态成员函数get_totalnum(),为了访问非静态数据成员,带有对象引用参数
    static int get_totalnum();
    static int get_totalnum(Student &stdref);
private:
    static int s_nTotalNum;                            //静态数据成员s_nTotalNum
    string m_strName;
    int m_nID;
};
//定义Student构造函数,每创建一个对象,记录学生总人数的s_nTotalNum自增1
Student::Student(string con_name, int con_id) :m_strName(con_name)
{
    s_nTotalNum++;
    m_nID = con_id;
}
//定义析构函数,每析构一个对象,s_nTotalNum减1
Student::~Student()
{
    s_nTotalNum--;
    cout << "destructor, totalnum = " << s_nTotalNum << endl;
    if (s_nTotalNum == 0)
        system("pause");
}
//定义获取学生姓名的函数
string Student::get_stdname()                      
{
    return m_strName;
}
//定义静态成员函数,获取s_nTotalNum值并显示了某个学生的姓名
int Student::get_totalnum(Student &stdref)
{
    cout << stdref.m_strName << " entered the school!" << endl;
    return s_nTotalNum;
}
//定义静态成员函数,获取静态数据成员s_nTotalNum的值
int Student::get_totalnum()
{
    return s_nTotalNum;
}
//初始化静态数据成员s_nTotalNum
int Student::s_nTotalNum = 0;                     

int main()
{
    //通过类名访问静态成员函数
    cout << "access to static func \"get_totalnum()\": totalnum = "
        << Student::get_totalnum() << endl;     
    //定义类对象std_tom
    Student std_tom("Tom", 20);                   
    //通过对象访问静态成员函数
    cout << std_tom.get_stdname() << ", totalnum = "
        << std_tom.get_totalnum(std_tom) << endl;

    return 0;
}

总结静态成员操作有如下几点:
● 类的普通成员函数可以访问类中的非静态及静态数据成员。
● 在类外部可以直接访问类的公有静态数据成员和公有普通数据成员,访问方式不同:公有普通数据成员只可以通过对象访问,公有静态数据成员既可以通过对象访问也可以通过类访问。
● 在类外可以直接访问类的公有静态成员函数和公有普通成员函数,访问方式不同:公有普通成员函数只可通过对象访问,公有静态成员函数既可以通过对象访问也可以通过类访问。

2.5.2 用const修饰的成员函数

● 常成员函数使得对数据的访问只限定为读取,而保护了数据不被修改,在只需要获取的场合,通常使用常成员函数实现。对于常数据成员的访问通常使用常成员函数完成。
●常成员函数可访问类中的const数据成员和非const数据成员,但不能改变它们,常成员函数不可调用非const成员函数。非const成员函数可以读取常数据成员,但不可修改。
● 常成员函数中的this指针为常量型,以防止对数据成员的意外修改。

#include <iostream>
#include <string>
using namespace std;
//定义Student类
class Student                                              
{
public:
    Student(string con_name, int con_id);
    ~Student();
    //用const声明常成员函数
    string get_stdname() const;                         
    void print_stdname();
private:
    string m_strName;//const string m_strName;
    int m_nID;
};
//定义Student的构造函数
Student::Student(string con_name, int con_id) :m_strName(con_name)
{
    m_nID = con_id;
}
Student::~Student()
{
}
//定义常成员函数,获取学生姓名
string Student::get_stdname() const                  
{
    //错误,常成员函数不可以修改成员的值
    //m_strName = "Paul";                               
    return m_strName;
}
//普通成员函数,显示学生姓名
void Student::print_stdname()                         
{
    //正确, 普通成员函数可以修改成员的值
    //m_strName = "Paul";                              
    cout << "std's name:" << m_strName << endl;
}
int main()
{
    Student std_tom("Tom", 20);
    //调用普通成员函数
    std_tom.print_stdname();    
    //调用常成员函数                     
    cout << std_tom.get_stdname() << endl;        
    system("pause");
    return 0;
}

总结常成员函数的使用规则:
● 若类中某些数据成员的值允许改变,另外的数据成员不可改变,则可将不需要改变的成员声明为用const修饰的常数据成员。可用非const成员函数获取常数据成员的值,访问或修改普通数据成员。
● 若类中所有的数据成员均不改变,则可将所有的数据成员用const修饰,然后用常成员函数获取数据成员,保证数据不被改变。
● 若定义的是常对象,则只能调用常成员函数。

有关static和const的博文:
1. http://www.cnblogs.com/xiaoyi115/p/3622891.html#commentform
2. http://www.cnblogs.com/10jschen/archive/2012/09/22/2698102.html

猜你喜欢

转载自blog.csdn.net/fengying2016/article/details/77604510