c++学习6--《c++必知必会》小结2

来源:互联网 发布:真人龙虎软件下载 编辑:程序博客网 时间:2023/12/03 09:18

1.指针比较的含义

在c++中一个对象可以有多个有效的地址,因此指针比较的不是地址问题而是对象的同一性问题

示例:
class Shape{...};

class Subject{...};

class Observed:public Shape,public Subject{...};

Observed * ob=new Observed;

Shape * s=ob;//预定义转换

Subject * ss=ob;//预定义转换

一个指向子类的指针可以与指向任何类型的基类进行比较,注意s和ss是不能比较的。多继承下对象具有多个地址。

当处理指向对象的指针或引用时,必须小心避免丢失类型信息,这样编译器会用原始地址比较,而不是调整一定偏移量完成。

ob==s//编译器会根据对象布局调整一定的偏移量使其相等

void * v=s;

if)ob==v)//丢失了类型信息,这样就是不相等了

2.常量成员函数 形式为fun()const;

2.1作用:不能修改对象的成员变量。同时当对象也为常量对象时只能调用该类型的函数

2.2非常量成员函数中this指针类型为X * const,那么对象的成员是可以修改的。常量成员函数中this指针类型为const X * const this,指向的对象是常量的,不可修改。常量成员函数中需要修改成员变量则变量声明为mutable。

class A{
public: mutable int temp;
A():temp(5)
{

}
public: void fun1() const
{
             temp=1;
}


void fun2()
{
          temp=3;
}
};


int main()
{
  A t;
  t.fun2();
  t.fun1();
  
  cout<<t.temp;
  return 0;
}

3.函数指针

3.1将函数地址赋值给一个函数指针时,无需显式地取得函数地址,编译器知道隐式地获取函数地址。

3.2同样调用函数指针所指向的函数而进行解引用操作也是不必要的。

3.3不可以将函数指针指向一个非静态成员函数。

4.指向成员函数和成员变量的指针并非指针

4.1获取非静态成员函数的地址时,得到的不是一个地址,得到的是一个指向成员函数的指针

4.2指向成员变量的指针,为了访问成员,需要将对象地址和成员的偏移量相加。指向成员函数的指针需要将对象的地址用作指针值this指针的值,和偏移量加减。

4.3指向成员函数的指针自身需要存储一些信息,比如指向虚函数或者非虚函数,到哪里找适当的虚函数表指针等。此类指针童话村实现为一个小型结构。

4.4指向成员函数指针的逆变性:存在从指向基类成员函数的指针到指向派生类成员函数指针的预定义转换(基类成员函数指针赋值给派生类成员函数指针),反之不然。

class A
{
public: int temp;
A():temp(5)
{

}
public: void fun1() 
{
             cout<<"fun1"<<endl;
}


void fun2()const
{
          cout<<"fun2"<<endl;
}
};
class B:public A
{
public :
void f()
{
tempB=3;
}
public:
int tempB;
};
void fun()
{
cout<<"haha"<<endl;
}
int main()
{
  A t;
  void (*fp)()=fun;//隐式赋值
  fp();//隐式调用
  (*fp)();//显示调用


  void (*fp2)=&fun;//显示赋值
  fp();
  
  //fp2=&A::fun1;//报错
  void (A::*fp3)()=&A::fun1;//成员函数指针定义方式
  void (A::*fp4)() const =&A::fun2;//必须加上const
  A * t2=&t;
  (t2->*fp3)();//调用fun1
  (t.*fp4)();//调用fun2
  //fp3();无法脱离类信息进行调用


  B b;
 //void (A::fp5)()=&B::f;//错误,这里是逆变性
 //(t.*fp5)();//会试图访问派生类中的数据成员tempB
  //void (B::fp5)()=&A::fun1;//vc++6.0下还是会报错 
  //(b.*fp5)();
  A * p=&b;//对比逆变性


  int B::*fp5=&A::temp;
  //int A::*fp6=&B::tempB;基类指针没有派生类中的新的成员变量
  cout<<b.*fp5<<endl;//输出为5,基类的成员变量值
  return 0;
}

5.处理函数和数组声明

int (**p)[n];//一个指针,指向一个指针,该指针指向一个具有n个元素的数组

int *(*p)[n];//一个指针,指向一个具有n个int * 类型的数组

int (**const fp)();//一个常量指针,指向一个指向函数的指针

int *(*fp)();//一个指针指向一个返回类型为int *  的函数

一个函数指针数组声明方式

5.1 int  (*arr[n])();//一个具有N个元素的数组,元素类型为指向返回值为int函数的指针 int(*)()fp[n]是错误的,因为函数修饰符()表示声明的结尾

5.2typedef int   (*fp)();

fp arr[n];

6.重载:在同一个作用域多个函数名字相同但参数信息不同overload

  重写:派生类和基类有相同函数名和参数信息override

0 0
原创粉丝点击