(C++) 为什么auto_ptr被弃用

☠️auto_ptr 的现状

在这里插入图片描述

在 C++ 中,智能指针一直是一个非常重要的模块。从 C++98 起就有了智能指针auto_ptr。但是其本身具有非常大的问题。

因此到了 C++11 便将其弃用,并提出了三个沿用至今的智能指针 unique_ptr; shared_ptr; weak_ptr

到了 C++17 更是直接移除了。具体原因请继续查看下文。

☠️弃用原因

复制 auto_ptr,会复制指针并转移所有权给目标:auto_ptr 的复制构造和复制赋值都会修改其右侧实参,而且“副本”不等于原值。


这里提到了两个关键词,复制转移所有权。复制大家都比较熟悉。一般我们认为的复制都是拷贝操作,包含潜拷贝和深拷贝。而所有权的转移并不与复制这个约定俗成的操作直接相关。

下文使用测试的编译器为:

gcc version 11.2.0 (x86_64-posix-seh-rev3, Built by MinGW-W64 project)

💀直接copy

#include <iostream>
#include <memory>

int main() {
    std::auto_ptr<int> ap1(new int{});
    std::printf("ap1=%p\n", ap1.get());

    std::auto_ptr<int> ap2 = ap1;
    std::printf("ap1=%p ap2=%p\n", ap1.get(), ap2.get());

    ap1 = ap2;
    std::printf("ap1=%p ap2=%p\n", ap1.get(), ap2.get());
}

我们观察到等号右侧的 auto_ptr 直接变为了空。这与我们平常编码的认知非常反直觉。

ap1=0000023a5e0d1780
ap1=0000000000000000 ap2=0000023a5e0d1780
ap1=0000023a5e0d1780 ap2=0000000000000000

💀函数传参

#include <iostream>
#include <memory>

void fun(std::auto_ptr<int> ap) {
    std::printf("test ap=%p\n", ap.get());
}

int main() {
    std::auto_ptr<int> ap(new int{});
    std::printf("main ap=%p\n", ap.get());
    fun(ap);
    std::printf("main ap=%p\n", ap.get());
}

同样对于函数传参,在不考虑编译器优化的情况下,上文代码表示的就是通过拷贝的方式传参,同样会使得 auto_ptr 置空。

main ap=00000159bcdd1780
test ap=00000159bcdd1780
main ap=0000000000000000

💀容器使用

通俗的说类就是将数据和函数封装到一起的一个集合。而我们调用对象的方法其实就是调用函数。

因此也会出现上文中函数对应的问题。

#include <memory>
#include <vector>

int main() {
    std::vector<std::auto_ptr<int> > arr;

    std::auto_ptr<int> ap(new int(100));
    // arr.push_back(ap);
}

而编译器对于标准库的实现不是简单的随便写写而是有一系列复杂的情况。而通过这堆实现在很多时候会直接从编译层面阻碍你的使用。

仅定义:

有趣的是仅定义居然可以生成二进制文件。

main.cpp: In function 'int main()':
main.cpp:5:22: warning: 'template<class> class std::auto_ptr' is deprecated: use 'std::unique_ptr' instead [-Wdeprecated-declarations]
    5 |     std::vector<std::auto_ptr<int> > arr;
      |                      ^~~~~~~~
In file included from D:/Qt/Tools/mingw1120_64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/memory:76,
                 from main.cpp:1:
D:/Qt/Tools/mingw1120_64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/bits/unique_ptr.h:57:28: note: declared here
   57 |   template<typename> class auto_ptr;
      |                            ^~~~~~~~
main.cpp:7:10: warning: 'template<class> class std::auto_ptr' is deprecated: use 'std::unique_ptr' instead [-Wdeprecated-declarations]
    7 |     std::auto_ptr<int> ap(new int(100));
      |          ^~~~~~~~
In file included from D:/Qt/Tools/mingw1120_64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/memory:76,
                 from main.cpp:1:
D:/Qt/Tools/mingw1120_64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/bits/unique_ptr.h:57:28: note: declared here
   57 |   template<typename> class auto_ptr;
      |                            ^~~~~~~~

使用成员函数:

而当我们调用成员函数时,就直接无法完成编译。

报错太多,此处就不展示了。

⭐END

🌟关注我

关注我,学习更多C/C++,算法,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值