静态成员

本文详细介绍了C++中静态成员的概念及其应用场景,包括静态数据成员和静态成员函数的特点与使用方法,并通过具体示例展示了如何在程序中正确使用静态成员。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.静态数据成员
可以定义类的静态成员,能够实现同类的多个对象之间数据共享。使用类的静态成员的优点是:
①静态成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突;
②静态成员可以实施封装,可以是私有成员,而全局对象不可以。
③静态成员是与特定类关联的,结构清晰。
静态数据成员是类的一种特殊数据成员,它以关键字static开始,
声明形式为:

class 类名{//类体

static 数据成员类型 数据成员名列表;//静态数据成员的声明
};

例如:

class Data{
public:
static int count ;//静态数据成员
int maxlevel;//非静态公有成员
Data(int i=0){
count++;
} //构造函数 
private :
int level;//非静态私有数据成员 
};// count设计的目的是计数Data类总共有多少个实例化对象。
int Data::count=0;//静态数据成员定义并初始化 

关于静态数据成员的说明:
(1)通常,非静态数据成员存在于类类型的每个对象中,静态数据成员则独立于该类的任何对象,在所有对象之外单独开辟空间存储。在为对象所分配的空间中不包括静态数据成员所占的空间。
(2)如果只声明了类而未定义对象,则类的非静态数据成员是不占存储空间的,只有在定义对象时,才为对象的数据成员分配空间。但是只要在类中定义了静态数据成员,即使不定义任何对象,也为静态数据成员分配空间,它可以在尚未建立对象时就被引用。
(3)访问静态成员时同样需要遵守公有及私有访问规则。
4)静态数据成员必须在类外部定义一次(仅有一次),静态成员不能通过类构造函数进行初始化,而是在类外定义时进行初始化。定义静态数据成员的方式为:
数据成员类型 类名::静态数据成员名=初值;
(5)静态数据成员可用作默认实参,非静态数据成员不能用作默认实参,因为它的值不能独立于所属的对象而使用。
(6)有了静态数据成员,各对象之间实现了数据共享,因此可以
不使用全局变量。
举例:

#include<iostream>
using namespace std;
class test{
    private:
        int x;
        int y;
    public:
        static int num;
        static int Getnum()
        {
            //x+=5;//错误,静态成员函数不能调用非静态数据成员
            num+=15;
            return num; 
        }
};
int test::num=10;
int main(){
    test a;
    cout<<test::num<<endl;//输出
    test::num=20;
    cout<<test::num<<endl;//输出20
    cout<<test::Getnum()<<endl;//输出35
    cout<<a.Getnum()<<endl;//输出50
    return 0; 
}

2.静态成员函数
成员函数也可以定义为静态的,在类中声明函数的前面加static就成了静态成员函数,声明的一般形式为:

class 类名{
    ...
    static 返回类型 函数名(类型1 参数名1,类型2 参数名2) {
        return count;//静态成员函数 
    }
};

例如:static int getcount(){
return count;//静态成员函数
}

和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。如果要在类外调用公有的静态成员函数,可以类作用域运算符(::)和通过对象名调用静态成员函数,不能通过类名来调用类的非静态成员函数。例如:

 cout<<Data::getcount()<<"\t"<<d.getcount(); 

静态成员函数与非静态成员函数的根本区别是:非静态成员函数有this指针,而静态成员函数没有this指针。因此,静态成员函数不能访问本类中的非静态成员。静态成员函数就是专门为了访问静态数据成员的。
静态成员函数不能被声明为const。

#include<iostream>
using namespace std;
class CTest{
    public:
        CTest(){
            s_total++;
            id=s_total;
            cout<<"构造"<<id<<" "; 
        }
        ~CTest(){
            s_total--;
            cout<<"析构"<<id<<" ";
        } 
        static int gettotal(){
            return s_total;
        }
        private:
            static int s_total;
            int id; 
};
int CTest::s_total=0;
int main(){
    CTest a,b,c;
    CTest *p=new CTest;
    cout<<"合计"<<CTest::gettotal()<<"  ";
    delete p;
    cout<<"合计"<<CTest::gettotal()<<"";
    return 0; 
} 
class Test {
    public:
        void init(){}
            static void output(){
            }
};
int main(){
    Test::init();//编译出错,因为不能通过类名来调用类的非静态成员 init 
    Test::output();
}
class Test{
    public:
        void init(){}
            static void output(){
            }
};
int main(){
    Test t;
    t.init();
    t.output();
    return 0;
}//编译通过,类的对象可以使用静态成员函数和非静态成员函数
class Test{
    public:
    void init(){}
        static void output(){
            cout<<x<<endl;
        }
    private:
        int x;
};
int main(){
    Test t;
    t.output();
    return 0; 
} //编译出错,因为静态成员函数不能使用非静态成员
class Test{
    public:
        void init(){
            output();
         }
         static void output(){
         }
 }; 
 int main(){
    Test y;
    y.output();//编译可以通过,类的静态成员函数可以被非静态成员函数调用, 
    return 0;
 }
class Test{
    public:
        Test(){m++;
         }
         ~Test(){m--;
         }
         static void output(){
            cout<<m<<endl;
         }
         private: 
         static int m;
}; 
//链接错误,因为类的静态数据成员在使用前必须先初始化。
//int  Test::m=0; 
int main(){
    Test t;
    t.output();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值