虚基类设计 c++

一个例子

在这里插入图片描述

首先大家看一个定义的一个虚基类
所谓的虚基类,是指类内包含virtual关键字定义的成员函数

class Abstract_base
{
public:
	virtual ~Abstract_base();
	virtual void interface() const =0;
	virtual const char* mumble() const {return m_mumble;}
protect:
	char* m_mumble;
}

上述的虚基类有以下特点:

  • 虚的析构函数。(必须的,否则继承的类将没法完全析构,delete BasePointer, BasePointer实际指向的是子类)
  • 两个虚的函数
    • 一个是接口
    • 一个是const char成员
    • 一个成员变量

这样的构造成员函数有什问题?
本人的分析
对于虚构造函数,似乎没问题;对于虚拟接口,也没问题,各个子类有自己的实现嘛;对于mumble,子类返回的时候,m_mumble进行了初始化?没有,因为子类没办法初始化 m_mumble, 除非用 Abstract_base::m_mumble这种方式。

class Abstract_base
{
    public:
    ~Abstract_base(){};   // not virtual functions
    virtual void interface() const{};
    virtual const char* mumble() const {return m_mumble;}
    protected:
    char* m_mumble;
};
class derived_from_base : public Abstract_base
{
    public:
    derived_from_base()
    {
        cout <<"derived ctor" << endl;
    }
    ~derived_from_base() 
    {
        cout << "~ derived dtor" << endl;
    }
    void interface() const override{}
    const char* mumble() const override{ return "asdfsd";}
};
int main()
{
    Abstract_base* b = new derived_from_base();
    delete b;
    return 1;
}
[Running] cd "c:\Users\ssas0e\" && g++ abstract_class.cpp -o abstract_class && "c:\Users\ssas0e\"abstract_class
derived ctor

[Done] exited with code=1 in 3.236 seconds

子类初始化父类的Protect 成员

class Abstract_base
{
    public:
    ~Abstract_base(){};
    virtual void interface() const{};
    virtual const char* mumble() const {return m_mumble;}
    protected:
    char* m_mumble;
};

class derived_from_base : public Abstract_base
{
    public:
    derived_from_base()
    {
        cout <<"derived ctor" << endl;
        char* p = new char[8];
        p[0] = '1';
        p[1] = '\0';
        Abstract_base::m_mumble = p ;
    }

    ~derived_from_base() 
    {
        cout << "~ derived dtor" << endl;
    }

    void interface() const override{}
    const char* mumble() const override{ return Abstract_base::mumble();}
    
};

int main()
{
   // Abstract_base();
    derived_from_base b;
    cout << b.mumble() << endl;
    return 1;
}

运行结果:

derived ctor
1
~ derived dtor

书上的分析
虽然这个class 被设计为一个抽象的base class(其中pure virtual function,使得abstract_base不可能拥有实例,),但它仍然需要一个显示的构造函数,以初始化器成员变量,m_mumble。如果没有这个初始化操作,子类得到的m_mumble是未经过初始化的。

你可能会争辩说,也许Abstract_base的设计者意图让每一derived class提供m_mumble的初始值。然而如果是这样,derived class 的唯一要求就是Abstract_base必须提供一个带有唯一参数的protect constructor.

Abstract_base::
Abstract_base(char* mumble_value=0):m_mumble(mumble_value)
{}

一般而言,class的data member应该被初始化,并且只能在constructor挥着在class种的其他member funtions中设定初始值。其他的操作会破坏封装性质,使class的维护和修改更加困难。

当然,你也可能争辩说,设计的者的错误并不在于未提供一个explicit constructor,而是它不应该在抽象的base class中声明 成员变量(数据成员,非指针)。这是比较强有利的论点,(把interface与implement分离),但它并不是普世道理。因为将“被共享的数据”取出来放在Base class中,毕竟是一种正当的操作。

读后评论
这里作者认为,虚基类是可以放data member的,因为这个data member是可以共享的数据。但是作者认为,上述的设计,应该提供一个显示的构造函数,不然子类就需要像我最开始的那种 Abstract_base::m_mumble的方式去给父类的成员变量assign ,破坏编程的封装性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值