Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shared_ptr维护对象数组的实现&访问方式的注意点 #82

Open
LiangZhisama opened this issue Jun 15, 2022 · 0 comments
Open

Comments

@LiangZhisama
Copy link

  • 课上提到不能直接使用智能指针维护对象数组,因为其所有删除方式都是delete p,而数组需要通过delete[] p;来删除。然而可以通过自定义删除方法来支持delete[]的操作

1. shared_ptr自定义delete[]删除方法的实现:

    void ArrayDeleter(TestClass *array) {
        delete [] array;    
    }
    int main()
    {
        const size_t size = 100;
        
   
        //使用函数指定
        std::shared_ptr<TestClass []> spFunc(new TestClass[size], ArrayDeleter);
        
        //使用lambda表达式
        std::shared_ptr<TestClass []> spLambda(new TestClass[size], [] (TestClass * tc) {delete [] tc;});

        std::shared_ptr<TestClass []> spDefaultDeleter(new TestClass[size], std::default_delete<TestClass[]>());

        return 0;
    }

即在定义shared_ptr时声明此指针的删除方式,其中TestClass即你期望使用的对象数组所在的类,ArrayDeleter是你自己定义的delete []删除函数的函数指针。

2.和unique_ptr的对比:

和shared_ptr相比,unique直接支持持有对象数组:

std::unique_ptr<int[]> p(new int[10]);//正常运行
std::shared_ptr<int[]> p(new int[10]);//报错:does not compile
 
std::unique_ptr<int, void(*)(int*)> p(new int[10],
    [](int* p){
        delete[] p;
    });
  • 由于unique_ptr支持对象数组的持有,其同时也必然支持使用[]对数组元素进行访问,但unique_ptr不支持*,->访问操作。
  • 而shared_ptr在访问元素时只能利用get()获得裸指针后配合*,->获取元素。
  • shared_ptr访问方法示例:(承接上方代码)
   void ArrayDeleter(TestClass *array) {
        delete [] array;    
    }

    int main()
    {
        //使用函数指定
        std::shared_ptr<TestClass []> spFunc(new TestClass[size], ArrayDeleter);

        //spFunc[0] = 10; //报错
        (spFunc.get())->b = 10;
        (spFunc.get() + 1)->b = 20;
        std::cout << "第一个元素:" << (spFunc.get())->b << std::endl;
        std::cout << "第二个元素:" << (spFunc.get() + 1)->b << std::endl;

        return 0;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant