无法访问已释放的对象_C++实用技巧分享,控制对象创建

Hello,大家好,今天给大家分享两个C++的小技巧。


在通常情况下,我们定义了一个普通的类,然后就可以创建该类的实例对象,但是在某些情况下,允许用户任意的创建对象并不是一个好的方法,这时我们就需要限制用户创建对象。
一般的,对象的创建分两种方式,一种是在栈上创建对象,另一种是在堆上创建对象,下面我们就从这两个方面来讨论如何限制用户操作。


1 只允许用户在堆上创建对象


所谓只允许用户在堆上创建对象,就是只允许用户使用new操作符来创建对象,换句话说要禁止用户在栈上创建对象。
也许你会想,根据类的构造函数和访问限制特点,可以将构造函数声明为私有,但是这样一来,new操作符也不能访问构造函数了。

class 


针对以上代码,我们希望"line1"和"line2"编译错误,"line3"编译正确,那么我们就需要对类的特殊函数做一些处理。
上面已经说到了,构造函数是不能声明为私有的,否则也会阻止在堆上创建对象,既然这样,构造函数就只能声明为公有了,还有什么方法可以阻止在栈上创建呢。
我们再仔细想一想,在C++中,有这样一条规则:当用户试图在栈上创建对象时,编译器会查找匹配且可以访问的构造函数和析构函数,如果其中一个无法访问,编译就会报错。
这似乎给了我们一点提示,将析构函数声明为私有,这样的话不就可以禁止用户在栈上创建对象了吗。

class 


我们编译一下,发现符合预期。
但是,马上下一个问题来了,如果你使用delete来删除创建出来的对象时,编译器还是报错了。
为此,我们可以再编写一个释放函数,在函数中调用delete操作符,这样所有的问题就都解决了。
下面是示例代码:

class 


好了,大功告成,但是,有一点需要注意,我们在成员函数Delete()中,删掉了this指针所指对象,这有点像对象的自杀行为,如果该对象再被引用将会报错,所以请确定不再使用该对象时,再调用删除函数,这个地方一定要注意。那么我们可以总结:使析构函数私有化,可以禁止在栈上创建对象。


2 只允许在栈上创建对象


这跟我们上一小节刚好相反,我们需要禁止new操作符创建对象,聪明的同学可能已经想到了,那就是将new和delete操作符声明为私有的即可。

class 


编译一下,正如我们所预想的,"line2"将不能通过编译,这就阻止了用户在堆上创建对象,是不是很神奇。


好了,关于今天的分享就到这里了,尽管这样的技巧在平时用的不多,但是在某些场景下的确是很好的处理办法。


例如,如果你正在编写一个同步锁或文件对象等,为了让锁自动打开和释放或者是让文件自动打开和关闭,你就使该类实例只能在栈上创建,在构造和析构函数中编写初始化与释放代码,这样用户创建的类对象就会自动管理资源,从而你也不必担心用户因为忘记释放资源而造成的种种坑了。

再比如有些工厂函数或类方法,不要求用户自行new对象,所以可以加限制,这些技巧并不多用,但在某些场景下还是很好用的,可以让用户更安全的使用类。等遇到实际问题了,可以往这方面想想,有个思路,平时有个印象即可
最后不要忘记点赞哦,您的支持就是对我最大的鼓励^_^

欢迎关注微信公众号-小豆君Qt分享

a29628a2a5b457983ec126f300644237.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将易语言的网页_访问_对象翻译成C++,可以使用C++的网络库来实现。以下是一个简单的示例: ```c++ #include <iostream> #include <string> #include <curl/curl.h> // 回调函数,用于获取HTTP请求的响应数据 size_t write_callback(char *ptr, size_t size, size_t nmemb, std::string *data) { data->append(ptr, size * nmemb); return size * nmemb; } int main() { // 初始化curl库 curl_global_init(CURL_GLOBAL_ALL); // 创建curl句柄 CURL *curl = curl_easy_init(); if (curl) { // 设置要访问的URL curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com"); // 设置回调函数 std::string response; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); // 执行HTTP请求 CURLcode res = curl_easy_perform(curl); if (res == CURLE_OK) { // 打印响应数据 std::cout << response << std::endl; } else { // 打印错误信息 std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl; } // 清理curl句柄 curl_easy_cleanup(curl); } // 清理curl库 curl_global_cleanup(); return 0; } ``` 这个示例使用libcurl库来实现HTTP访问。其中,write_callback()函数是一个回调函数,用于获取HTTP请求的响应数据。curl_easy_setopt()函数用于设置curl句柄的选项,例如要访问的URL、回调函数等等。curl_easy_perform()函数用于执行HTTP请求。如果执行成功,那么响应数据会被存储在response字符串中。如果执行失败,那么会打印错误信息。最后,通过curl_easy_cleanup()函数和curl_global_cleanup()函数来清理curl句柄和curl库。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值