纯虚函数与抽象类


title: 纯虚函数与抽象类
date: 2021-06-19 16:56:53
tags: [C++]


纯虚函数与抽象类

纯虚函数与抽象类

  • 纯虚函数:用 virtual 声明且赋值 0 的没有函数体的函数。
  • 抽象类:包含纯虚函数的类。

抽象类的使用

  1. 抽象类只能作为基类来派生新类使用,不能创建抽象类的对象。
  2. 抽象类的指针和引用可以指向由抽象类派生出来的类的对象。
// 抽象类
Class A {
public: 
    virtual void show() = 0; // 纯虚函数
}; 
int main()
{
    /*
    1. 抽象类只能作为基类来派生新类使用
    2. 抽象类的指针和引用可以指向由抽象类派生出来的类的对象
    */
    A a; // error 抽象类,不能创建对象
    A *a1; // ok 可以定义抽象类的指针
    A *a2 = new A(); // error, A是抽象类,不能创建对象
}

实现抽象类

抽象类中,在成员函数内可以使用纯虚函数,在构造函数和析构函数内部不能使用纯虚函数

如果一个类从抽象类派生而来,它必须实现了基类中的所有纯虚函数,才能成为非抽象类。

// A为抽象类
class A {
public:
    virtual void f() = 0;  // 纯虚函数
    void g(){ this->f(); }
    A(){}  // 构造函数
};

class B : public A{
public:
    void f(){ cout<<"B:f()"<<endl;}  // 实现了抽象类的纯虚函数
};

int main(){
    B b;
    b.g();
    return 0;
}

重要点

纯虚函数使一个类变成抽象类

// 抽象类至少包含一个纯虚函数
class Base{
public: 
    virtual void show() = 0; // 纯虚函数
    int getX() { return x; } // 普通成员函数

private:
     int x; 
}; 

抽象类类型的指针和引用

// 抽象类至少包含一个纯虚函数
class Base{
public: 
    virtual void show() = 0; // 纯虚函数
    int getX() { return x; } // 普通成员函数

private:
     int x; 
}; 

class Derived : public Base { 
public: 
    void show() { cout << "In Derived \n"; } // 实现抽象类的纯虚函数
    Derived(){} // 构造函数
}; 

int main() 
{ 
    //Base b;  // error! 不能创建抽象类的对象
    //Base *b = new Base(); error!
    
    Base *bp = new Derived(); // 抽象类的指针和引用可以指向由抽象类派生出来的类的对象
    bp->show();
    return 0; 
}

如果我们不在派生类中覆盖纯虚函数,那么派生类也会变成抽象类

// Derived为抽象类
class Derived: public Base 
{ 
public: 
//    void show() {}
}; 

抽象类可以有构造函数

// 抽象类
class Base { 
protected: 
    int x; 
public: 
   virtual void fun() = 0; 
   Base(int i) { x = i; }  // 构造函数
}; 
// 派生类
class Derived: public Base 
{ 
    int y; 
public: 
    Derived(int i, int j) : Base(i) { y = j; } // 构造函数
    void fun() { cout << "x = " << x << ", y = " << y; }
}; 

int main() 
{ 
    Derived d(4, 5); 
    d.fun(); 
    return 0; 
} 

构造函数不能是虚函数,而析构函数可以是虚函数

// 抽象类
class Base  {
public:
    Base(){ cout << "Constructor: Base" << endl; }
    virtual ~Base(){ cout << "Destructor : Base" << endl; }
    
    virtual void func() = 0;
};

class Derived: public Base {
public:
    Derived(){ cout << "Constructor: Derived" << endl; }
    ~Derived(){ cout << "Destructor : Derived" << endl;}
    
    void func(){cout << "In Derived.func()." << endl;}
};

当基类指针指向的派生类对象销毁时,我们可能希望调用适当的析构函数。 如果析构函数不是虚函数,则只能调用基类析构函数

完整实例

class Base 
{ 
    int x; 
public: 
    virtual void fun() = 0; 
    int getX() { return x; } 
}; 

class Derived: public Base 
{ 
    int y; 
public: 
    void fun() { cout << "fun() called"; }  // 实现了fun()函数
}; 

int main(void) 
{ 
    Derived d; 
    d.fun(); 
    return 0; 
} 

PDF:链接 密码:8sue

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值