C++静态成员函数
静态成员属于类但不属于对象,静态成员变量在类内声明类外定义,变量在类外分配空间。
目录
一、静态成员函数
1.静态成员函数和非静态成员函数的调用区别
2.静态成员函数调用非静态成员
3.非静态成员函数调用静态成员
二、静态函数不可以声明为虚函数
三、静态成员函数不可以声明为const
四、static关键字不构成重载
五、静态成员函数的地址与绑定
一、静态成员函数
1.静态成员函数和非静态成员函数的调用区别
静态成员属于类,而非对象,因此可以通过类名直接访问。
访问非静态成员需要this指针,静态成员函数没有,因此静态成员函数不能直接访问非静态成员变量,但能访问静态成员变量。
问:静态成员变量和静态成员函数,都是属于类的,可以使用类名和作用域运算符“::”来调用它们。当定义了类对象之后,也可以如同普通的成员变量和成员函数一样,使用对象和点运算符“.”来调用它们,为什么呢?
答:因为如果创建了类一定在实例化对象之前执行,只要类存在,就可以调用对象。
class A
{
public:
static void print()
{
cout << c << " ";
}
static int c;
private:
int a;
int b;
};
int A::c = 0;
int main()
{
A a;
a.print();
a.c = 2;
A::print();
A::c = 3;
return 0;
}
2.静态成员函数调用非静态成员
静态成员函数如何才能访问静态成员函数和静态成员变量呢?
class A
{
public:
static void print(A x)
{
cout << x.a << " ";
x.print1();
cout << c << " ";
}
void print1()
{
cout << b << endl;
}
static int c;
private:
int a=1;
int b=2;
};
int A::c = 0;
int main()
{
A a;
a.print(a);
a.c = 2;
A::print(a);
A::c = 3;
return 0;
}
3.非静态成员函数调用静态成员
非静态成员函数调用静态成员函数和变量
class A
{
public:
static int c;
static void print()
{
cout << c << " ";
}
void print1()
{
c = 2;
print();
}
private:
int a = 1;
int b = 2;
};
int A::c = 3;//调用静态成员需要用类加域名限定符::调用,因为静态成员属于类
int main()
{
A a;
a.print1();
return 0;
}
二、静态函数不可以声明为虚函数
静态成员函数没有this指针,不能声明为虚函数
class StaticMemberFuncTest
{
public:
static virtual void test() {};
};
编译报错为:virtual
关键字不可以与 static
一起使用。
error C2216: 'virtual' cannot be used with 'static'
三、静态成员函数不可以声明为const
未修改成员变量的函数可以声明为常函数,加上 const
关键字,但静态成员函数不可以。
class StaticMemberFuncTest
{
public:
static void Test() const {
//;
};
};
静态成员函数上不允许使用访问限定词,如 const
, volatile
等。
四、static关键字不构成重载
同样重载只针对非静态成员函数
class StaticMemberFuncTest
{
public:
static void Test() {}
void Test() {}
};
编译报错
error C2686: cannot overload static and non-static member functions with the same parameter types
note: could be 'void StaticMemberFuncTest::Test(void)'
note: or 'void StaticMemberFuncTest::Test(void)'
五、静态成员函数的地址与绑定
对于类
class StaticMemberFuncTest
{
public:
static int StaticFunc() {/**/};
int MemberFunc() {/**/};
};
1.静态成员函数的存储函数地址时,可以用普通的函数指针;
// 静态成员函数指针
int (*funcptr1)() = &StaticMemberFuncTest::StaticFunc;
// 成员函数指针
int (StaticMemberFuncTest::*funcptr2)() = &StaticMemberFuncTest::MemberFunc;
2.在使用STL的bind时,不需要传入类成员函数的指针
// 绑定静态成员函数
std::bind(&StaticMemberFuncTest::StaticFunc);
// 绑定成员函数
std::bind(&StaticMemberFuncTest::MemberFunc, this);