C++ FUCTION

黎 浩然/ 9 5 月, 2022/ C/C++, 计算机/COMPUTER/ 0 comments

/**
* @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;}
};

可以看到,抽象类也可以有构造函数和成员变量!

Share this Post

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注

*
*