类和对象经典面试题(一)

定位new表达式

已分配的原始内存空间调用构造函数初始化一个对象

格式:

new(place_address) type 或者new(place_address) type(initializer_list)

其中place_address必须是一个指针,initializer_list是类型的初始化列表

使用场景:

一般配合内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显式调用构造函数进行初始化

void Test()
{
	Test* pt = (Test*)malloc(sizeof(Test));
	new(pt) Test;		//如果Test类的构造函数有参数时此处则需要传参
}

对象创建的方式

在C++中类的对象创建分两种,一种是静态的建立如A a,另一种是动态建立,如A* ptr = new A;

区别:

  1. 静态建立一个对象,是由编译器为对象在栈空间中分配内存。是通过移动栈顶指针挪出适当的空间然后在这片内存空间上调用构造函数形成一个栈对象(直接调用构造函数)
  2. 动态建立类对象,是使用new运算符将对象建立在堆空间中
    1. 执行operator new()函数,在堆空间中分配合适空间
    2. 调用构造函数构造对象,初始化这片内存空间

由此引出了一个经典的面试题:

  1. 创建一个类,只能在堆上创建对象
  2. 创建一个类,只能在栈上创建对象

一.只能在堆上创建对象

  1. 方法一:容易想到将构造函数私有化

    构造函数私有化之后无法在类外部调用构造函数来构造类对象,只能用new运算符来建立对象,但是new运算符实际底层分两步,在调用构造函数时因其已私有化所以无法调用

  2. 方法二:

    当对象建立在栈上面时是由编译器分配内存空间,调用构造函数来构造栈对象,当对象使用完之后编译器会调用析构函数来释放栈对象所占的空间

    假设类的析构函数私有,编译器无法调用析构函数来释放内存。所以**在为类对象分配栈空间时会先检查类的析构函数的访问性。**如果类的析构函数是私有的则编译器不会在栈空间上为类对象分配内存

    class A
    {
    	public:
        	A(){}
            void destroy(){delete this;}
        private:
        	~A(){}
                
    };
    
  3. 提供一个static函数来完成构造

    class A
    {
        public:
        	static A* create()
            {
                return new A();
            }
        
        	void destroy()
            {
                delete this;
            }
        private:
        	A(){}
        	~A(){}
        	A(const A&) = delete;		//将编译器默认生成的拷贝构造函数删除掉,防止别人									 //调用拷贝构造函数生成对象
    }
    

二.只能在栈上创建对象

只有使用new运算符对象才会建立在堆上。因此只要禁用new运算符就可以实现类对象只能建立在栈上,将operator new()设为私有即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值