当前位置: 首页 > news >正文

政府网站建设出现的问题及对策我要看今日头条

政府网站建设出现的问题及对策,我要看今日头条,廊坊视频优化排名,张槎网站制作C编程技巧专栏:http://t.csdnimg.cn/eolY7 目录 1.概述 2.RAII的应用 2.1.智能指针 2.2.文件句柄管理 2.3.互斥锁 3.注意事项 3.1.禁止复制 3.2.对底层资源使用引用计数法 3.3.复制底部资源(深拷贝)或者转移资源管理权(移动语义) 4.RAII的优势和挑战 5.总…

C++编程技巧专栏:http://t.csdnimg.cn/eolY7

目录

1.概述

 2.RAII的应用

2.1.智能指针

2.2.文件句柄管理

2.3.互斥锁

3.注意事项

3.1.禁止复制

3.2.对底层资源使用引用计数法

3.3.复制底部资源(深拷贝)或者转移资源管理权(移动语义)

4.RAII的优势和挑战

5.总结


1.概述

        RAII是Resource Acquisition Is Initialization的缩写,即“资源获取即初始化”。RAII原则的基本思想是将资源的生命周期与对象的生命周期绑定在一起。它是C++语言的一种管理资源、避免资源泄漏的惯用法,利用栈的特点来实现,这一概念最早由Bjarne Stroustrup提出。在函数中由栈管理的临时对象,在函数结束时会自动析构,从而自动释放资源,因此,我们可以通过构造函数获取资源,通过析构函数释放资源。这种自动管理资源的方式可以大大减少资源泄漏、野指针和其他与资源管理相关的问题。常见的写法为:

Object() {// acquire resource in constructor
}
~Object() {// release resource in destructor
}

 2.RAII的应用

2.1.智能指针

智能指针是RAII原则在内存管理中的一个典型应用。C++11引入了多种智能指针类型,如std::unique_ptr、std::shared_ptr和std::weak_ptr,它们可以自动管理动态分配的内存。

例如,使用std::unique_ptr可以确保在不需要动态分配的内存时自动释放它:

#include <iostream>
#include <memory>class MyClass {
public:MyClass() { std::cout << "MyClass created\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }
};int main() {{std::unique_ptr<MyClass> ptr(new MyClass()); // MyClass对象被创建// 当ptr离开这个作用域时,它会自动释放所指向的MyClass对象} // MyClass对象在这里被销毁,输出"MyClass destroyed"return 0;
}

在这个例子中,当ptr离开其作用域时,std::unique_ptr的析构函数会被调用,从而释放它所指向的MyClass对象。这种自动的内存管理方式避免了手动调用delete可能导致的错误。

2.2.文件句柄管理

另一个常见的应用是使用RAII原则管理文件句柄。通过创建一个封装了文件句柄的类,可以确保在不需要文件时自动关闭它。

例如:

#include <fstream>
#include <iostream>class FileWrapper {
public:FileWrapper(const std::string& filename, std::ios_base::openmode mode): file_(filename, mode) {if (!file_.is_open()) {throw std::runtime_error("无法打开文件: " + filename);}}~FileWrapper() {file_.close(); // 在析构函数中关闭文件句柄}// 提供对内部文件的访问(如果需要的话)std::fstream& file() { return file_; }private:std::fstream file_; // 封装文件句柄的成员变量
};

在这个例子中,FileWrapper类的构造函数打开一个文件,并在析构函数中关闭它。这确保了即使在异常情况下,文件句柄也会被正确关闭。

2.3.互斥锁

在多线程编程中,std::lock_guard, std::unique_lock, std::shared_lock等也利用了RAII的原理,用于管理互斥锁。当这些类的等对象创建时,会自动获取互斥锁;当对象销毁时,会自动释放互斥锁。

std::lock_guard的构造函数如下:

template< class Mutex > class lock_guard;

std::lock_guard的析构函数会自动释放互斥锁,因此,我们可以通过std::lock_guard来管理互斥锁,从而避免忘记释放互斥锁。如:

std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx); // unlock when lock is out of scope

不使用RAII的情况下,我们需要手动释放互斥锁,如下所示:

std::mutex mtx;
mtx.lock();
// ...
mtx.unlock();

3.注意事项

在资源管理类中小心copy行为

  • 拷贝RAII对象必须考虑其管理的资源,针对其资源做出拷贝行为的实现
  • 常见的RAII对象拷贝行为:拒绝拷贝、引用计数法、深拷贝、资源所有权转移

并非所有资源都是基于堆的(heap-based),对于这种对象不能直接使用智能指针,需要自定义其资源管理类。例如:为了说明锁的资源管理行为,我们这里给定义一个锁,来替代C++里的锁

struct MyMutex {MyMutex() {printf("Construct MyMutex\n");}~MyMutex() {printf("Deconstruct MyMutex\n");}
};

其上锁解锁行为:

void lock(MyMutex *) {printf("lock\n");
}void unlock(MyMutex *) {printf("unlock\n");
}

锁的资源管理类,在构造函数获取资源(加锁),在析构函数释放资源(解锁):

struct Lock {
private:MyMutex *myMutex;
public:explicit Lock(MyMutex *mutex) : myMutex(mutex) {lock(myMutex);}~Lock() {unlock(myMutex);}
};

使用:

int main() {MyMutex myMutex;{printf("---------\n");Lock lk(&myMutex);printf("---------\n");// 离开代码块将自动析构局部对象,因此会释放锁}
}
/*
Construct MyMutex
---------
lock
---------
unlock
Deconstruct MyMutex
*/

潜在风险,如果发生了拷贝行为:

Lock l1(&mutex);
Lock l2(l1);

那么将立即死锁(Linux里一般是非递归锁,重复加锁会造成死锁)

3.1.禁止复制

继承nocopyable,或者将拷贝相关函数设置为delete。如:

//[1]
class NonCopyable
{
protected:NonCopyable(const NonCopyable&){}NonCopyable& operator=(NonCopyable&){}
};或//[2]
class NonCopyable
{
public:NonCopyable(const NonCopyable&)=delete;NonCopyable& operator=(const NonCopyable&)=delete;
};

3.2.对底层资源使用引用计数法

思想:维护一个计数器,当最后一个使用者被销毁时,才真正释放资源,如:

struct Lock {
private:shared_ptr<MyMutex> mutexPtr;
public:// 将unlock函数设置为删除器explicit Lock(MyMutex *mutex) : mutexPtr(mutex, unlock) {lock(mutexPtr.get());}// 不必声明析构函数,因为mutexPtr是栈上对象,所以会被默认释放,那么智能指针就会调用其释放器unlock
};

3.3.复制底部资源(深拷贝)或者转移资源管理权(移动语义)

在资源管理类中提供对原始资源的访问

  • API常需要要求访问原始资源,所以RAII资源管理类应该提供访问原始资源的接口
  • 对原始资源可以由显示转换或者隐式转换获得.其在安全性和方便性上各有取舍

智能指针提供了get接口来访问原始资源

在其中要注意,不可以get一个智能指针去初始化另一个智能指针,否则会发生重复释放

int main() {shared_ptr<MyMutex> p1 = make_shared<MyMutex>();{shared_ptr<MyMutex> p2(p1.get());cout << p1.use_count() << " " << p2.use_count() << endl;
//        1 1
//        p2离开代码块,释放其管理的资源,p1指针指向被释放的内存}
}

程序将异常退出

4.RAII的优势和挑战

优势:

  1. 自动资源管理:通过绑定资源的生命周期与对象的生命周期,RAII自动处理资源的获取和释放,减少了手动管理的错误。

  2. 代码简洁性:RAII原则鼓励将资源管理逻辑封装在类中,使代码更加清晰和易于维护。

  3. 异常安全性:当使用RAII时,即使在异常情况下,资源也会被正确释放,这有助于提高程序的健壮性。

挑战:

  1. 资源所有权的转移:在使用RAII时,需要仔细考虑资源所有权的转移。例如,在使用智能指针时,需要明确何时使用std::move来转移所有权。

  2. 与旧代码的兼容性:在将RAII原则应用于现有代码库时,可能需要大量的重构工作来适应新的资源管理方式。

  3. 学习曲线:对于初学者来说,理解和正确应用RAII原则可能需要一些时间和经验。

5.总结

        RAII原则为C++程序员提供了一种强大且优雅的资源管理方法。通过将资源的生命周期与对象的生命周期绑定在一起,RAII不仅简化了资源管理,还提高了代码的健壮性和可维护性。然而,为了充分利用RAII的优势,程序员需要仔细设计类的接口和实现,并考虑到资源所有权和资源转移的问题。

http://www.hkea.cn/news/408127/

相关文章:

  • 微网站怎么做滚动中国万网域名注册官网
  • 个人如何免费建网站seo在线优化工具 si
  • 双线主机可以做彩票网站吗网络推广合作协议
  • 做外贸的b2b网站域名批量查询系统
  • 建设网站需要哪些职位网站建设策划书
  • 苏州网站建设哪里好网站点击排名优化
  • 网站建设收费标准策划百度推广关键词越多越好吗
  • 网站怎么做更新吗如何建立网页
  • 国外建设工程招聘信息网站tool站长工具
  • 专业做相册书的网站电商网站建设制作
  • 银川网站开发公司电话东莞网
  • 环境保护局网站管理制度建设百度指数的主要功能有
  • 安装wordpress提示500错误关键词优化的策略有哪些
  • 企业网站建设公司排名深圳高端seo公司助力企业
  • 做网站套餐网站seo
  • 网站上的代码网页怎么做的下载百度软件
  • 网站功能模块建设搜狗推广
  • 网站做推广有用吗网站页面设计
  • 做简报的网站广州搜发网络科技有限公司
  • 南乐县住房和城乡建设局网站制作网站的步骤是什么
  • 金华做网站最专业的公司搜易网提供的技术服务
  • wordpress适合门户网站吗怎么营销自己的产品
  • 常用的网站类型有哪些seo优化专员编辑
  • 网站专题框架怎么做海阳seo排名
  • 手机网站代码下载黄页网站推广服务
  • 做网站前端多少钱在线bt种子
  • wordpress+模版+推荐专业网站seo推广
  • 浦项建设公司员工网站2023免费推广入口
  • 如何查询某个网站的设计公司最新推广注册app拿佣金
  • 八宝山做网站公司打广告