英伟达圣诞偷袭,200亿美元收购Groq
2025/12/26 21:03:17
只需要在将构造函数声明为如下形式即可
class A { public: A() = default; private: A(const A&) = delete; };如果使用下面的声明则会报错
int main() { A a; A b = a; // compile-time error }运行g++编译会报错
main.cpp: In function ‘int main()’: main.cpp:10:15: error: use of deleted function ‘A::A(const A&)’ 10 | A b = a; | ^ main.cpp:5:9: note: declared here 5 | A(const A&) = delete; | ^struct Counter { int* p; Counter(int v) { p = new int(v); } ~Counter() { delete p; } }; int main() { Counter a(1); Counter b(2); a = b; }使用gdb调试,设置断点在a=b处
(gdb) print a $1 = {p = 0x55555556aeb0} (gdb) print *a No symbol "operator*" in current context. (gdb) print b $2 = {p = 0x55555556aed0}可以看出a和b中的成员变量p的值是不同的
现在step next,再看看a和b的值
18 } (gdb) print a $7 = {p = 0x55555556aed0} (gdb) print b $8 = {p = 0x55555556aed0}我们可以看到,二者都一样了,即两个变量的成员变量p都指向了同一个地址,地址内的值是2
(gdb) print *a->p $9 = 2 (gdb) print *b->p $10 = 2然后退出主函数之前调用析构函数
(gdb)s Counter::~Counter(this=0x7fffffffdd00,__in_chrg=<optimized out>)at main.cpp:99delete p;(gdb)n10}(gdb)print this->p$13=(int *)0x55555556aed0(gdb)print *this->p$14=1431655786可以看到地址内的值已被其他的值替换
问题是删除了a的值,那b的值也删除了,原来a的p值并没有被delete
(gdb) print /x *0x55555556aeb0 $17 = 0x1相当于这里有个指针变量被悬空了,由于C++没有垃圾回收,那么这个内存就一直占据内存,如果数量庞大则会导致内存溢出。
如果要避免这种情况的发生,则可使得运算符设置为不允许拷贝
struct Counter { int* p; Counter(int v) { p = new int(v); } ~Counter() { delete p; } Counter& operator=(const Counter&) = delete; }; int main() { Counter a(1); Counter b(2); a = b; }使用g++进行编译
jx@jx-virtual-machine:~/src/cpp$ g++ main.cpp -o main main.cpp: Infunction‘int main()’: main.cpp:19:7: error: use of deletedfunction‘Counter&Counter::operator=(const Counter&)’19|a=b;|^ main.cpp:12:12: note: declared here12|Counter&operator=(const Counter&)=delete;|^~~~~~~~