成员函数指针

时间:2024-07-02 21:22:02编辑:揭秘君

静态成员函数没有this指针,是怎么实现被对象访问的。

类的静态函数被该类所有的实例所共享,因而没有this指针,不能访问类的非静态成员,示例如下:
class cls
{
plublic:
cls(){ m_value = 0;};
virtual ~cls(){};
int m_value;
static int m_static_value; //静态成员变量
static int foo(); //静态函数
int foo2();
};
int cls::foo()
{
++cls::m_static_value; // 类的静态函数访问类的静态成员变量
}
int cls::foo2()
{
++m_value;
}
int cls:m_static_value = 0;
cls var;
var.foo2(); //调用类的非静态函数
cls::foo(); //调用类的静态成员函数
cls var1; // var1的m_static_value 此时为1,因为静态成员变量,被类cls的所有实例所共享


如何理解变量,指针,引用?

你问的这个话题太大。关于指针和引用要讲的东西很多。
我的理解:
指针: 其实指针这个概念在谭浩强的这本书上是这样说的,指针就是地址,指针值就是地址值。指针变量就是存放指针的

变量,所以一定不要将指针与指针变量搞混淆了。指针仅仅是一个地址值,而指针变量就是存放指针(也就是地址的变量)

指针的定义:
例如整型指针: int *p;p是一个指向int类型数据的指针变量。里面存放的地址(也就是指针)是一个int类型变量的地址。指针变量时

有类型的,例如p的类型就是int *表示p是一个指向int类型的指针变量。如何知道一个指针变量的类型呢,最简单的方法就是去掉变

量定义语句中的变量名,剩下的部分就是其类型,这种方法适用于所有的变量定义,例如int a;a的类型是int 。 int b[10];b的类

型是int[]表示是一个数组(关于数组类型这里不谈,因为这个问题很微妙,其实在c、c++中没有数组类型这个概念,包括函数类型也

是一样的),int *c;c的类型是int *。int ** d;d的类型就是int **;所以通过这种方法来判断一个变量的类型是很方便的。

说道指针变量,我们必须说到得有几个方面。

1.指针类型。

这个很重要,一个指针是有类型的,也就是一个地址是有类型的。具体说是某一个地址会指向不同类型的数据,这是不一样的,例如

int *p;p是指向int型数据。 double*p1;p1是指向double型数据。但是p和p1本身在内存中占用的空间是4个字节(对于32位的系统来说

),如果是在TC中编译c程序,应该是2个字节了(dos操作系统是16位的)。有人说地址不就是一个值吗,类似于0xfffdddcc这样的地址

数值,为什么还分什么类型呢,我要说的是这个关系很大。我们知道指针是有运算的,int *p=&a;那么p++到底加了多少呢,不要以为

是将p里面的地址值加了1,这是完全想当然。实际上加了sizeof(int)这么多个字节。也就是说加了一个int元素应该占用的字节,这

样在数组中我们可以通过这种方式从上一个元素很方便的让指针变量指向下一个元素。p+5的话实际上是加了p+sizeof(int)*5这么多

个字节。 另外一点事指针的类型决定了当指针解引用的时候其所以指向的内存单元中的二进制数据如何解释的问题。例如int *p=&a;

那么(*p)取得的数字就是一个整型数据,如果(*((char *)p))得到的就是一个字符型数据了。p本来指向的是int型数据(有4个字节)的

首地址,如果将其强制转换为一个指向char类型的指针变量,那么在解引用的时候只取第一个字节的数据,并将其解释为一个ascii码

代表的字符。 还有如果是一个指向函数的指针变量,我们可以通过此指针变量直接调用函数。例如int(*function)(int);此时

function指向一个函数,此函数具有一个int参数,返回一个int值。那么通过指针可以这样调用该类型的函数了int a=function

(100); 或者int a=(*function)(100);其实要不要解引用都是可以的。不过以前是需要解引用的,现在c标准规定这两种方法都可以。

总的来说指针的类型很重要。

2.指针与数组。

我们向一个函数传递数组的时候一般是传递数组名,我们知道数组名是一个代表数组中第一个元素的地址并且数组名是不可以当左值

的。其实你又没有想过数组名到底是什么呢。有人说其实数组名就是一个指针常量,是一个不可以改变的指针常量。例如:int a[10]

={1,2,3,4,5,6,7,8,9,10}; 那么a可能的类型是int * const a;注意const的位置(关于指针常量和常量指针,这个以后说),那么这种

说法到底对不对呢。我们可以通过sizeof运算符来计算某一种数据类型占用的存储空间。例如 sizeof(10)的值为4,注意这里我都假

设在32位的操作系统上面编译。其实sizeof(10)和sizeof(int)是一样的,仅仅是求这种类型的数据占用多少内存空间,而不是说具体

的某个数据占用的空间,因为对于10这个文字常量来说根本不会占用内存空间的,其实随着程序直接编码到源程序中的,不存在分配

内存的问题。那么我们这样计算sizeof(a);是不是如我们所愿得到的是4呢。 结果可能会有意外,因为其值是sizeof(int)*10也就是

40个字节,显然这个字节数是整个数组占用的字节数。而不是int *类型的指针变量占用的字节数,我们知道一个地址只占用4个字节

那么这说明数组名绝对不是简单的int*类型。但是数组确实具有int*的特性。例如int*p=a;这是不会报错的。而且在函数之间传递的

时候也是采用这样的方式:
void print(int b[10]){}
调用函数:
print(a);
或者:
print(&a[0]);
都是一样的。

注意在某一个函数内对形参进行sizeof:
void print(int c[100])
{
sizeof(c); // 此时表达式的结果是4,而不是100。因为这里int c[100]与int *c是一样的,c不是数组名(数组名是不能作为左值

的)
}

3. 指针与函数

一个指针可以指向一个函数,指针可以作为函数参数,函数可以返回一个指针类型的数据。

指向函数的指针: 指向函数的指针,实际上此指针就是函数代码的入口地址。我们可以通过这样的方式调用函数。例如:

void print1(int x)
{
cout<<"hello "<<x<<endl;
}

void print2(int y)
{
cout<<"hello "<<y<<endl;
}

那么在main函数中可以这样写:

void (*p)(int)=print1;//函数名代表函数入口地址值,和数组一样,print1不仅仅是一个地址。

p(10);

p=print2;

p(20);

这都是可以的,另外我们可以通过一个指针数组存放指向函数的指针:

void (*aa[2])(int)={print1,print2};

for(int i=0;i<2;i++)
{
aa[i](i); //通过函数指针循环调用里面的函数
}

关于各种指向函数指针的声明,请自己查阅有关资料。


引用:

引用相当于别名,其实你直接将其当做一个别名就可以了。引用与指针的区别: 引用必须初始化,而且初始化之后不可更改,指针

却可以。


c++静态成员函数里,为何不能直接使用this指针?

静态成员函数并不是针对某个类的实例对象,而是属于整个类的,为所有的对象实例所共有。他在作用域的范围内是全局的,独立于类的对象之外的。他只对类内部的静态成员变量做操作。当实例化一个类的对象时候,里面不存在静态成员的。this指针是相当于一个类的实例的指针,this是用来操作对象实例的内容的,既然静态成员函数和变量都是独立于类的实例对象之外的,他就不能用this指针。也不能操作非静态成员。再有你要想想设计静态成员的用意在哪里,就会更加明了了


成员函数指针的函数指针

1.成员函数指针通过引用操作符(.*)从对象或引用获取成员;2.成员函数指针通过箭头操作符(->*)从对象指针获取成员。比如:char(Screen::*pf)()const=&Screen::get;其中get()为类Screen的成员函数;Screen mScreem;Screen *pScreen=&mScreem;(pScreen->*pf)();相当于调用get; 静态函数指针的调用和声明方法,和普通的函数指针相同。

关于空类指针为什么可以调用类的成员函数

class MyClass{public:int i;void hello(){printf("hello/n");}void print(){printf("%d/n", i);}};void main(){MyClass* pmy = NULL;
pmy-hello();}看上面的这段代码,似乎很诡异。 用一个空指针调用成员函数,简直是天大的错误,可以遗憾的是,却是可行的,至少对于上面的这段程序来说,不会照成错误。
之前运行的原因。
大家知道,每个对象,都有一个指向自己的this指针,这个指针的值,将会因为对象的不同而不同,它的作用主要就是用来区分不同的对象,这样你就可以根据它


带指针的函数怎么调用?

什么叫带指针的函数?说清楚点嘛?
1.如果是返回值是指针
char* getname()
{
char* pname=new char[23]; //返回指针必须是函数释放后并未释放的内存空间,
cout<<"input your name:\n"; //一般返回两种情况,一是在函数中像该函数一样动态分配堆内存
cin.getline(pname,22); //二是返回指针指向参数中地址,如: int* max(int a,int b) { return &a; }
pname[22]='\0';
return pname;
}
int main()
{
char* name=getname();
cout<<"your name is: "<<name<<endl;
delete []name; //记得动态释放分配内存
return 0;
}
2.参数是指针类型
常见的是通过指针或引用交换两个数的值
void swa(int* p1,int* p2)
{
int temp=*p1; *p1=*p2; *p2=temp;
}
int main()
{
int a=2,b=3;
swa(&a,&b); //传递地址
return 0;
}
附解:你可以把指针看做是一种复合类型,它之所以可以修改参数值,本质是因为
对指针解除引用*p形式是操作的参数所存数据内存空间,但如果它不解除引用,它
并不会修改参数的值:如
void swa(int* p1,int* p2) //函数意思是最初始在函数参数块中定义两个指针p1,p2,使
{ //p1指向a,p2指向b,下面函数体只是使指针指向地址改变,成了
//p1指向b,p2指向a。但并未对a,b内存空间操作,当函数调用结束后,指针p1,p2
//也释放了,所以并未起任何作用
int* temp;
temp=p1; p1=p2; p2=temp;
}
int main()
{
int a=2,b=3;
swa(&a,&b); //传递地址
cout<<a<<" "<<b;
return 0;
}
这个函数并不会交换a,b的值


如何从静态成员函数调用成员函数的指针

通常不建议这样做哦。这样做通常意味着设计上有严重的缺陷。因为:静态成员函数是不需要类的对象就可以调用的。类的对象都不存在当然不能直接调用了。如果一定要调用,你可以用以下三种方式,创建一个类对象在进行调用1、用参数传递进一个内的对象;2、在静态成员函数中创建一个临时对象。3、创建一个该类的全局对象仅举一例#include #include using namespace std;class A{public: void foo() { cout << "Yes" << endl; } static void boo() { static A oneObj; oneObj.foo(); }};int main(){ A::boo(); A::boo(); return 0;}


在c++中,类的静态成员函数可以通过类的指针访问类的非静态数据成员吗?

可以的,不过要间接访问。看下面的例子#include using std::cout;using std::endl;class A{ int data; public: A(int i):data(i) { coutdata++; coutdata<<endl;//通过指针访问内部非静态对象;但不能用this指针直接来访问 } }; int main() { A b(2); b.access(&b);//静态成员函数访问 return 0; }


c++如何在一个类中定义指向另外一个类的指针

直接定义即可。比如已有一个类class A, 再定义一个类class B,这样在B的定义中,就可以有一个A*类型的成员变量。
比如
class B
{
A * a;

};
这里的B::a就是一个A*类型的指针。
需要注意的是,要使用这种形式的定义,要么A的定义在B的上方,要么在B定义前加一个A类的声明。

class A;
class B
{
A * a;

};


上一篇:静海一中吧

下一篇:镜花奇缘