C++ FUCTION
/**
* @file func_pointer.cpp * @brief 函数指针的使用!
* @author Ernest
* @version v1
* @date 2019-07-20
*/
#include<iostream>
using namespace std;
/**
* @brief 定义了一个变量pFun,这个变量是个函数指针,指向返回值为空且参数为一个整数的
函数!
*/
void (*pFun)(int);
/**
* @brief 代表一种新类型,不是变量!所以与上述的pFun不一样!
*/
typedef void (*func)(void);
void myfunc(void) { cout<<"asda"<<endl; }
void glFun(int a){ cout<<a<<endl;}
int main(){
// 先分析函数名的行为
func pfun = myfunc;
pfun();
pfun = &myfunc;
pfun();
//pfun = &&myfunc; //error: invalid conversion from ‘void*’ to ‘func {aka void (*)()}’
cout << (void *)(myfunc) << endl; //0x56037a00095a
cout << (void *)(&myfunc) << endl; //0x56037a00095a
//cout << (void *)(&&myfunc) << endl; //错误,常量不能取地址 pfun = *myfunc;
pfun();
pfun = **myfunc;
pfun();
cout << (void *)(*myfunc) << endl; //0x56037a00095a
cout << (void *)(**myfunc) << endl; //0x56037a00095a
// 由上面的分析可知 * 和 & 不完全是可逆的!
// 因为常量只要落在地址空间内就可以解引用!
// 但是常量本身是不能取地址的!
pFun = glFun;
pFun(2);
(*pFun)(2);
(**pFun)(2);
cout << (void *)pFun << endl; //0x558fe2600989
cout << (void *)(*pFun) << endl; //0x558fe2600989
cout << (void *)(**pFun) << endl; //0x558fe2600989
//((void (*)(int))(&pFun))(2); //Segmentation fault
cout << (void *)(&pFun) << endl; //0x558fe2802138 // 综合上面的试验可知函数指针和函数名的异同:
// 1) 函数指针变量和函数名都可以一直解引用
// 2) 函数指针变量解引用就是变量本身的地址,与函数无关
// 3) 函数名解一次应用仍然是函数的地址,再解引用就报错
}
纯虚函数
// 抽象类
class A {
public:
virtual void show() = 0; // 纯虚函数
/* Other members */
};
- 纯虚函数:没有函数体的虚函数(=0)
- 抽象类:包含纯虚函数的类
抽象类只能作为基类来派生新类使用,不能创建抽象类的对象
// A为抽象类
class A { public:
virtual void f() = 0; // 纯虚函数
void g(){ this->f(); }
A(){} // 构造函数
};
class B : public A{
public:
void f(){
cout<<"B:f()"<<endl;
}
// 实现了抽象类的纯虚函数
};
virtual只需要在最早一次函数声明中出现就可以!
如下,构造函数不能是虚(构造)函数,但是析构函数可以是虚(析构)函数
// 抽象类
class Base {
protected:
int x;
public:
Base(){ cout << "Constructor: Base" << endl; }
virtual ~Base(){ cout << "Destructor : Base" << endl; }
virtual void func() = 0;
Base(int i) { x = i; } // 构造函数
};
class Derived: public Base {
public:
Derived(){ cout << "Constructor: Derived" << endl; }
~Derived(){ cout << "Destructor : Derived" << endl;}
void func(){cout << "In Derived.func()." << endl;}
};
可以看到,抽象类也可以有构造函数和成员变量!