1.实例化对象时候会动态申请空间以存储该对象。对于数据类型(数据类型有基本数据类型,自定义数据类型,及对于他们的迭代类型(指针,数组))来说,类型也被存储(也许编译时候就分配到代码区一部分空间),对于自定义的类来说,空间中存放static变量(函数定义目前不知道是否在这部分空间)等。下面代码验证:
#include <iostream>
using namespace std;
class A
{
public:
int i;
static int j;
static int k;
static void func1() {}
void func() {}
};
int A::j = 0;
int A::k = 0;
typedef void (*FUNC)();
int main()
{
A a;
cout << sizeof(a) << endl;
cout << sizeof(A) << endl;
cout << &a << endl;
cout << &a.i << endl;
cout << &A::func << endl;
cout << &A::i << endl;
cout << &A::j << endl;
cout << &A::k << endl;
cout << &A::func1 << endl;
return 0;
}
2.当进行访问时候,通过对象或对象指针访问成员时候,可以用.或->访问到任何成员变量和成员函数(但类内定义的类型(typedef int INT)不能用这种方式访问),这种方法访问非static成员(成员函数和成员变量)时候,对象绑定,对于static成员访问,虽然前面加了对象名,但并没有对象绑定。(对于绑定,函数成员变量好理解,用对象指针表明我们调用的是哪个对象的成员变量。而对于成员函数程序中只保存一份,貌似不用对象绑定,但细想可以知道,我们需要用对象指针作为参数传给函数,函数内部调用时通过对象指针找到相应变量)。
class A
{
public:
typedef int INT;
}
int main()
{
A a;
a.INT i = 0;//error;
}
3.对于成员函数指针我们通过对象或对象的指针去访问成员函数的指针是不行的,因为这个时候得考虑函数只有一份,取地址用不到对象绑定(不像调用函数那样需要对象),那么编译器对于对象或指针调用函数指针方式就报错。(但static成员可以用对象或对象指针调用,这也是内部规定吧)。对于非类内部的全局函数,其函数名表示指针取引用也表示指针星取也表示指针(和数组一样,整个函数无法用名字表示,也无法拷贝赋值),要想取到函数地址需要使用&A::func1其函数名在使用时如下:
class A
{
public:
int i;
void func1() {}
void func2() { cout << func1 << endl; }//error指向绑定函数的指针只能用于调用函数。
static void func3() {}
}
int main()
{
A a;
A::func1;//error;
A::func3;//ok;
a.func3;//ok;
&a.i;//这样可以因为取成员变量的地址也需要对象绑定。
}
4.对于类型内的变量名,类型的存储空间有各个变量,函数等。对于A::调用,如下:
class A
{
public:
int i;
void func1() {}
void func2() { cout << func1 << endl; }//error指向绑定函数的指针只能用于调用函数。
static void func3() {}
}
int main()
{
A a;
A::func1;//error成员函数也无法这样取指针;
A::func3;//ok;
A::i;//error这样不可以,需要对象绑定。
}
5.对于命名空间::和类名A::两种方式。对于类内的static成员A::和命名空间一样,A::还表示使用的是类型空间里变量而非对象中变量。的如下:
class A
{
public:
int i;
static int j;
void func1() {}
static void func2() {}
}
void (*func)();
int main()
{
A::j ;
int j = A::j;
A::func2();
func = &A::func2;
func = A::func2;
func = *A::func2;
}
但A::对于非static函数而言,不仅表示命名空间,还表示与对象绑定。对象绑定,表示调用函数和变量前要绑定该对象(是对成员变量地址指针的绑定,及取成员变量或函数地址时候绑定),而并非成员函数和变量类型发生了变化(当时是想类型变成了A::类型,这是不对的,对函数来说也不是加了一个参数)。所以当取到成员变量的值时候,还是原来类型。如下:
class A
{
public:
int i;
int A::j;
int A::*k;
void func1() {}
static void func2() {}
}
name space xxx
{
int xx1;
}
int main()
{
int *xx2 = &xxx::xx1;
A::j ;
int j = A::j;
A a;
a.i = 0;
a.k = &A::j;
a.*(a.k);//取值方式。
void (A::*func)() = &A::func1;//取成员函数地址唯一方式。
(a.*func)();
}
纯虚函数无法取其地址。
6.对于int A::func(A::type t){}和int A::i = 1;(static);是一样的,需要指明空间对于里面参数也是一样。
7.对于成语函数用.或->调用时对象不但表示所属关系(函数地址寻找用到)还会自动将该对象作为参数传给该函数。所以成员函数和普通函数式不同的。static 成员函数和普通函数类型一样(不隶属某个对象)A::表示命名空间和std相似。对于成员变量,不存在传参数,所以成员变量的类型和外部类型一样没有变化。对于成员函数一般不用&a.func或a.func这样没有显示出其对象参数(对象参数用一个固定表示A::表示,而非a.)。c++规定取成员函数地址的方式是&A::func;定义成员函数指针时也要显式定义void A::*func();