【C++】设计一个类,该类不能被继承(自己笔记)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Wan_shibugong/article/details/82686315

一、不能被继承的要求

  1. 构造函数设置为私有
    因为创建子类时需要访问父类的构造函数
  2. 析构函数设置为私有
    因为销毁子类时需要访问父类的析构函数

    所以一个类不能被继承需要将析构函数和构造函数设置为私有的。

    但是两个函数被设置为私有后,这样一来这个类在其他地方不能实例化,没有存在的意义。

二、解决不能继承的类不能实例化的问题

1、通过静态方法来解决

这时候你是不是想到了静态方法,是啊,我们可以通过静态方法来返回类的实例,然后通过另一个静态方法来释放该类对象。代码如下:

静态成员函数不属于类对象所有(属于类的一部分)可以创建一个类来调用静态成员函数
也可直接不创建一个类,Base::来调用静态成员函数,因为他的生命周期是全局存在的,

class Base
{
public:
    static Base* getInstance(int n)
    {
        Base* pa;//这一步跳过
         pa = new Base();   //执行到这一步会执行一个构造函数来构造一个Base
        pa->_num = n;
        return pa;
    }
    static void destructInstance(Base* pInstance)
    {
        delete pInstance;     //在这里会调用析构函数
        pInstance = NULL;
    }

private:
    Base()
    {
        cout<<"Base::Base"<<endl;
    }
    ~Base()
    {
        cout<<"Base::~Base"<<endl;
    }
public:
    int _num;
};

int main()
{
    Base* pInstance  = Base::getInstance(10);
    cout<<pInstance->_num<<endl;
    Base::destructInstance(pInstance);

    return 0;
}

你可能会问,为什么必须返回指针而不返回对象的引用呢?这里必须返回指针,而不能像如下代码一样返回引用:

class Base
{
public:
    static Base& getInstance(int n)
    {
        Base par;
        par.num = n;
        return par;
    }
    static void destructInstance(Base& pInstance)
    {
        pInstance.~Base();
    }
private:
    Base(){cout << "construct Base" << endl;}
    ~Base()
    {
        cout << "destruct Base" << endl;
    }
public:
    int num;
};

当返回引用时,在输出num之前,对象就已经被析构了。因为在static Base& getInstance()函数中声明的对象Basepar是局部变量,当函数运行完,该变量就会被释放掉,而返回的却是已经被释放掉的对象的引用,这无疑会造成内存泄漏。所以,只能通过new来动态申请堆上的内存,然后返回指针,而不能返回引用。
可是这样一来,类A虽然不能被继承,但却只能在堆上创建对象,而不能在栈上创建对象。要知道很多时候,我们只想创建一个临时对象,使用栈空间会更高效方便一些。

也不能返回一个类,因为在其他函数需要创建一个类来接受这个类,又回到了最初的问题(因为在其他函数不能对该类进行实例化)

    static Base getInstance(int n)
    {
        Base par;
        par.num = n;
        return par;
    }

如何才能使我们的类既不能被继承,又能够在堆和栈上都可以创建对象呢?

2、使用友源(堆和栈上都可以创建对象)

友源函数可以访问类的私有成员

class Base
{
public:
        friend void test();
private:
    Base(int x)
        :_num(x)
    {
        cout<<"Base::Base"<<endl;
    }
    ~Base()
    {
        cout<<"Base::~Base"<<endl;
    }
public:
    int _num;
};

class Derived:public Base
{
public:
    int _a;
};

void test()
{
    cout << "--------------object on heap-----------------" << endl;
    Base *pfc = new Base(9); // 堆上的对象
    cout << "num is: " << pfc->_num << endl;
    delete pfc;
    cout << "-------------Object on stack-----------------" << endl;
    Base fc(10);  // 栈上的对象
    cout << "num is: " << fc._num << endl;

    //Derived d;//这样仍然不可以,因为创建派生类仍然需要调用基类的构造函数
}


int main()
{
    test();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Wan_shibugong/article/details/82686315