zoukankan      html  css  js  c++  java
  • C++中两种创建对象的方式

     在C++中,为了让某个类只能通过new来创建(即如果直接创建对象,编译器将报错),应该()

    正确答案: B   你的答案: D (错误)

    将构造函数设为私有
    将析构函数设为私有
    将构造函数和析构函数均设为私有
    没有办法能做到

    当时没有多想,觉得不太可能。事后想起来才发现这很容易做到,实质上还是内存管理的问题。

     

    只能做堆上创建对象

     

    在C++中,类的创建分为两种。一种是静态创建,即直接创建对象;另一种是动态创建对象,即通过 new 创建,如 T *t = new T。要想正确回答上题,就必须知道这两种创建方式的区别。

    1 静态创建

    由编译器在栈中为对象分配内存,通过移动栈顶指针获得合适大小的空间,然后调用对象的构造函数生成对象。

    2 动态创建

    通过new在堆中创建对象。这个过程分为两步:首先在堆中找到合适大小的空间并分配,然后调用对象的构造函数生成对象。

    因为两者都需要调用对象的构造函数,所以通过将构造函数私有化的做法是行不通的。那么还有其他办法吗?这是就需要了解静态创建的另一个特点了。

    编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。

    所以我们只需要将析构函数私有化就可以组织直接创建对象了。由于栈的创建和释放都需要由系统完成的,所以若是无法调用构造或者析构函数,自然会报错。

    当然为了我们能够正确释放动态创建的对象,我们必须提供一个公有函数,该函数的唯一功能就是删除对象本身

     测试代码如下:

    #include<iostream>
    using namespace std;
    class test
    {
    private:
    	~test(){ cout << "test destroy" << endl; }
    public:
    	void destroy()
    	{
    		delete this;
    	}
    };
    int main()
    {
    	//test p;//编译器报错test::~test()不可访问
    	test *p = new test;
    	p->destroy();
    }

    只能在栈上创建对象

     
    既然可以做到只在堆上创建对象,同样的我们可以只在栈上创建对象。
    其实理解了这个理念,不难想到我们只需要让new操作符无法使用即可,要做到这件事,我们可以将new操作符重载并设置为私有访问即可。是不是很巧妙的方法~

    重载new的同时最好重载delete

    #include<iostream>
    using namespace std;
    class test
    {
    private:
    	void* operator new(size_t t){}
    	void operator delete(void* ptr){}
    public:
    	~test()
    	{
    		cout << "test destroy" << endl;
    	}
    };
    int main()
    {
    	//test *A = new test;
    	//编译器报错函数test::operator new 不可访问
    	test A;
    
    上面是在堆上动态的创建,下面是在栈上静态的创建
    }
  • 相关阅读:
    QTableWidget控件总结<一>
    软件工程概论9
    软件工程概论8
    软件工程概论7
    软件工程概论6
    软件工程概论5
    软件工程概论4
    软件工程概论3
    软件工程概论2
    安装gocode教程
  • 原文地址:https://www.cnblogs.com/fenglongyu/p/7653390.html
Copyright © 2011-2022 走看看