C++11 类的六大基本成员函数默认生成,default字段的含义

2023-11-02

  1. 总览

    • 核心

      • 编译器会为一个类按需自动生成成员函数.

      • C++98:构造,析构,拷贝构造,拷贝赋值.

      • C++11:有了右值,就多了两个,移动构造和移动赋值.

    • 功能

      • 构造: 无参构造.T()

      • 析构: 调用成员变量析构.~T()

      • 拷贝构造: 同类型对象初始化.T a, b = a;

      • 拷贝赋值: 同类型对象赋值.T a,b; b = a;

      • 移动构造: 同类型右值初始化.T a = T();

      • 移动构造: 同类型右值赋值.T a; a = T();

    • 机制

      • 一般来说未定义,用到了,就添加.

      • 不过后面就有情况分析

    • C++98

      • 没有定义拷贝的任意一个,用到了都会构造.

    • C++11

      • 自定义了移动,赋值,析构.

      • 就隐式说明有资源操作,默认构造很可能无法满足,虽然也有可能满足,但是编译器就不冒险添加了.

      • 不过编译器也提供了很方便的机制,可以很轻易的表明需要生成默认.

      • =default即可.

      • 所以任意存在一个,其他一般的都不自动生成.除了析构这种必要的.

    • 生成类型

      • publicinline.

      • 析构函数则和父类一致.

    • 所有函数

      class T {
      public:
         T(){}
         ~T(){}
         T(const T&){}
         T& operator=(const T&){}
         T(T&&){}
         T& operator=(T&&){}
      };
      
      • 如上六种.

    • 生成

      • 采用std::move(T),最终匹配和类型实现有关.

  2. 生成

    • 按需生成

      • 没有用到就不会生成.

    • 生成拷贝构造

      [root@localhost test]# g++ test.cpp -std=c++11 -g
      [root@localhost test]# gdb ./a.out -q
      Reading symbols from /root/cppfile/test/a.out...done.
      (gdb) disassemble /r main
      Dump of assembler code for function main():
        0x00000000004007bd <+0>:     55      push   %rbp
        0x00000000004007be <+1>:     48 89 e5        mov    %rsp,%rbp
        0x00000000004007c1 <+4>:     53      push   %rbx
        0x00000000004007c2 <+5>:     48 83 ec 28     sub    $0x28,%rsp
        0x00000000004007c6 <+9>:     48 8d 45 e0     lea    -0x20(%rbp),%rax
        0x00000000004007ca <+13>:    48 89 c7        mov    %rax,%rdi
        0x00000000004007cd <+16>:    e8 6e 00 00 00  callq  0x400840 <T::T()>
        0x00000000004007d2 <+21>:    48 8d 45 d0     lea    -0x30(%rbp),%rax
        0x00000000004007d6 <+25>:    48 89 c7        mov    %rax,%rdi
        0x00000000004007d9 <+28>:    e8 62 00 00 00  callq  0x400840 <T::T()>
        0x00000000004007de <+33>:    48 8d 55 d0     lea    -0x30(%rbp),%rdx
        0x00000000004007e2 <+37>:    48 8d 45 e0     lea    -0x20(%rbp),%rax
        0x00000000004007e6 <+41>:    48 89 d6        mov    %rdx,%rsi
        0x00000000004007e9 <+44>:    48 89 c7        mov    %rax,%rdi
        0x00000000004007ec <+47>:    e8 d1 00 00 00  callq  0x4008c2 <T::operator=(T const&)>
        0x00000000004007f1 <+52>:    bb 00 00 00 00  mov    $0x0,%ebx
        0x00000000004007f6 <+57>:    48 8d 45 d0     lea    -0x30(%rbp),%rax
        0x00000000004007fa <+61>:    48 89 c7        mov    %rax,%rdi
        0x00000000004007fd <+64>:    e8 a2 00 00 00  callq  0x4008a4 <T::~T()>
        0x0000000000400802 <+69>:    48 8d 45 e0     lea    -0x20(%rbp),%rax
        0x0000000000400806 <+73>:    48 89 c7        mov    %rax,%rdi
        0x0000000000400809 <+76>:    e8 96 00 00 00  callq  0x4008a4 <T::~T()>
        0x000000000040080e <+81>:    89 d8   mov    %ebx,%eax
        0x0000000000400810 <+83>:    eb 26   jmp    0x400838 <main()+123>
        0x0000000000400812 <+85>:    48 89 c3        mov    %rax,%rbx
        0x0000000000400815 <+88>:    48 8d 45 d0     lea    -0x30(%rbp),%rax
        0x0000000000400819 <+92>:    48 89 c7        mov    %rax,%rdi
        0x000000000040081c <+95>:    e8 83 00 00 00  callq  0x4008a4 <T::~T()>
        0x0000000000400821 <+100>:   48 8d 45 e0     lea    -0x20(%rbp),%rax
        0x0000000000400825 <+104>:   48 89 c7        mov    %rax,%rdi
        0x0000000000400828 <+107>:   e8 77 00 00 00  callq  0x4008a4 <T::~T()>
        0x000000000040082d <+112>:   48 89 d8        mov    %rbx,%rax
        0x0000000000400830 <+115>:   48 89 c7        mov    %rax,%rdi
        0x0000000000400833 <+118>:   e8 78 fe ff ff  callq  0x4006b0 <_Unwind_Resume@plt>
        0x0000000000400838 <+123>:   48 83 c4 28     add    $0x28,%rsp
        0x000000000040083c <+127>:   5b      pop    %rbx
        0x000000000040083d <+128>:   5d      pop    %rbp
        0x000000000040083e <+129>:   c3      retq
      End of assembler dump.
      (gdb) break main
      Breakpoint 1 at 0x4007c6: file test.cpp, line 10.
      (gdb) r
      Starting program: /root/cppfile/test/./a.out
      
      Breakpoint 1, main () at test.cpp:10
      10          T a;
      (gdb) info source
      Current source file is test.cpp
      Compilation directory is /root/cppfile/test
      Located in /root/cppfile/test/test.cpp
      Contains 14 lines.
      Source language is c++.
      Compiled with DWARF 2 debugging format.
      Does not include preprocessor macro info.
      (gdb) !cat /root/cppfile/test/test.cpp
      #include<string>
      class T {
      public:
         int a;
         int b;
         std::string c{"122345"};
      };
      
      int main() {
         T a;
         T b;
         a = b;
         return 0;
      }
      
      
      • 上面的汇编可以看到.实现了一个赋值构造T::operator=(T const&).

      • 以及需要的构造和析构.

    • 默认拷贝构造

      [root@localhost test]# g++ test.cpp -std=c++11 -g
      [root@localhost test]# gdb ./a.out -q
      Reading symbols from /root/cppfile/test/a.out...done.
      (gdb) break main
      Breakpoint 1 at 0x4007c6: file test.cpp, line 10.
      (gdb) r
      Starting program: /root/cppfile/test/./a.out
      
      Breakpoint 1, main () at test.cpp:10
      10          T a;
      (gdb) disassemble main
      Dump of assembler code for function main():
        0x00000000004007bd <+0>:     push   %rbp
        0x00000000004007be <+1>:     mov    %rsp,%rbp
        0x00000000004007c1 <+4>:     push   %rbx
        0x00000000004007c2 <+5>:     sub    $0x28,%rsp
      => 0x00000000004007c6 <+9>:     lea    -0x20(%rbp),%rax
        0x00000000004007ca <+13>:    mov    %rax,%rdi
        0x00000000004007cd <+16>:    callq  0x400828 <T::T()>
        0x00000000004007d2 <+21>:    lea    -0x20(%rbp),%rdx
        0x00000000004007d6 <+25>:    lea    -0x30(%rbp),%rax
        0x00000000004007da <+29>:    mov    %rdx,%rsi
        0x00000000004007dd <+32>:    mov    %rax,%rdi
        0x00000000004007e0 <+35>:    callq  0x4008aa <T::T(T const&)>
        0x00000000004007e5 <+40>:    mov    $0x0,%ebx
        0x00000000004007ea <+45>:    lea    -0x30(%rbp),%rax
        0x00000000004007ee <+49>:    mov    %rax,%rdi
        0x00000000004007f1 <+52>:    callq  0x40088c <T::~T()>
        0x00000000004007f6 <+57>:    lea    -0x20(%rbp),%rax
        0x00000000004007fa <+61>:    mov    %rax,%rdi
        0x00000000004007fd <+64>:    callq  0x40088c <T::~T()>
        0x0000000000400802 <+69>:    mov    %ebx,%eax
        0x0000000000400804 <+71>:    jmp    0x400820 <main()+99>
        0x0000000000400806 <+73>:    mov    %rax,%rbx
        0x0000000000400809 <+76>:    lea    -0x20(%rbp),%rax
        0x000000000040080d <+80>:    mov    %rax,%rdi
        0x0000000000400810 <+83>:    callq  0x40088c <T::~T()>
        0x0000000000400815 <+88>:    mov    %rbx,%rax
        0x0000000000400818 <+91>:    mov    %rax,%rdi
        0x000000000040081b <+94>:    callq  0x4006c0 <_Unwind_Resume@plt>
        0x0000000000400820 <+99>:    add    $0x28,%rsp
        0x0000000000400824 <+103>:   pop    %rbx
        0x0000000000400825 <+104>:   pop    %rbp
        0x0000000000400826 <+105>:   retq
      End of assembler dump.
      (gdb) !cat test.cpp
      #include<string>
      class T {
      public:
         int a;
         int b;
         std::string c{"122345"};
      };
      
      int main() {
         T a;
         T b(a);
         return 0;
      }
      
      
      • 修改的只有一点点a=b改成b(a).

      • 可以看到这里调用的拷贝构造.T::T(T const&).

    • 反汇编

      • 通过objdump -d a.out可以查看_ZN1T的只有三个.

      • 分别对应,构造析构,拷贝构造.

      0000000000400828 <_ZN1TC1Ev>:
      000000000040088c <_ZN1TD1Ev>:
      00000000004008aa <_ZN1TC1ERKS_>:
      
      
      • _Z表示符号需要解密,1T,长度和符号.C1表示构造,Ev表示无参.

      • 具体可参考itaniumC++符号加密规则进行反向解密.

      • 最简单的就是c++filt指令获取结果.

      
      [root@localhost test]# c++filt _ZN1TC1Ev  _ZN1TD1Ev _ZN1TC1ERKS_
      T::T()
      T::~T()
      T::T(T const&)
      
      
    • 移动须知

      • 使用std::move,移动成员变量和父类.

      • 函数匹配,使用移动还是拷贝和匹配有关.

    • 智能移动

      [root@localhost test]# make
      g++ test.cpp -std=c++11 -g
      gdb ./a.out -q -ex 'break main' -ex 'r' -ex 'disassemble main' -ex 'c' -ex '!cat test.cpp'
      Reading symbols from /root/cppfile/test/a.out...done.
      Breakpoint 1 at 0x400a86: file test.cpp, line 27.
      Starting program: /root/cppfile/test/./a.out
      
      Breakpoint 1, main () at test.cpp:27
      27          T a;
      Dump of assembler code for function main():
        0x0000000000400a7d <+0>:     push   %rbp
        0x0000000000400a7e <+1>:     mov    %rsp,%rbp
        0x0000000000400a81 <+4>:     push   %rbx
        0x0000000000400a82 <+5>:     sub    $0x48,%rsp
      => 0x0000000000400a86 <+9>:     lea    -0x30(%rbp),%rax
        0x0000000000400a8a <+13>:    mov    %rax,%rdi
        0x0000000000400a8d <+16>:    callq  0x400b9e <T::T()>
        0x0000000000400a92 <+21>:    lea    -0x50(%rbp),%rax
        0x0000000000400a96 <+25>:    mov    %rax,%rdi
        0x0000000000400a99 <+28>:    callq  0x400b9e <T::T()>
        0x0000000000400a9e <+33>:    lea    -0x50(%rbp),%rax
        0x0000000000400aa2 <+37>:    mov    %rax,%rdi
        0x0000000000400aa5 <+40>:    callq  0x400c40 <std::move<T&>(T&)>
        0x0000000000400aaa <+45>:    mov    %rax,%rdx
        0x0000000000400aad <+48>:    lea    -0x30(%rbp),%rax
        0x0000000000400ab1 <+52>:    mov    %rdx,%rsi
        0x0000000000400ab4 <+55>:    mov    %rax,%rdi
        0x0000000000400ab7 <+58>:    callq  0x400c4e <T::operator=(T&&)>
        0x0000000000400abc <+63>:    mov    $0x0,%ebx
        0x0000000000400ac1 <+68>:    lea    -0x50(%rbp),%rax
        0x0000000000400ac5 <+72>:    mov    %rax,%rdi
        0x0000000000400ac8 <+75>:    callq  0x400c12 <T::~T()>
        0x0000000000400acd <+80>:    lea    -0x30(%rbp),%rax
        0x0000000000400ad1 <+84>:    mov    %rax,%rdi
        0x0000000000400ad4 <+87>:    callq  0x400c12 <T::~T()>
        0x0000000000400ad9 <+92>:    mov    %ebx,%eax
        0x0000000000400adb <+94>:    jmp    0x400b03 <main()+134>
        0x0000000000400add <+96>:    mov    %rax,%rbx
        0x0000000000400ae0 <+99>:    lea    -0x50(%rbp),%rax
        0x0000000000400ae4 <+103>:   mov    %rax,%rdi
        0x0000000000400ae7 <+106>:   callq  0x400c12 <T::~T()>
        0x0000000000400aec <+111>:   lea    -0x30(%rbp),%rax
        0x0000000000400af0 <+115>:   mov    %rax,%rdi
        0x0000000000400af3 <+118>:   callq  0x400c12 <T::~T()>
        0x0000000000400af8 <+123>:   mov    %rbx,%rax
        0x0000000000400afb <+126>:   mov    %rax,%rdi
        0x0000000000400afe <+129>:   callq  0x400980 <_Unwind_Resume@plt>
        0x0000000000400b03 <+134>:   add    $0x48,%rsp
        0x0000000000400b07 <+138>:   pop    %rbx
        0x0000000000400b08 <+139>:   pop    %rbp
        0x0000000000400b09 <+140>:   retq
      End of assembler dump.
      Continuing.
      copy assign
      [Inferior 1 (process 11575) exited normally]
      #include<string>
      #include<iostream>
      
      class D {
      public:
         D(){}
         ~D(){}
         D(D&&){}
         D(const D&){}
         D& operator=(const D&){
             std::cout << "copy assign" << std::endl;
         }
      };
      
      class T {
      public:
         int a;
         int b;
         std::string c{"122345"};
         D d;
         T(){}
         T(const T&){}
         T& operator=(T&&)=default;
      };
      
      int main() {
         T a;
         T b;
         a = std::move(b);
         return 0;
      }
      
      
      • 可以根据输出看到,使用的std::move,但是匹配的是拷贝赋值,因为没有实现移动赋值函数.

      • 这就是memberwise moves

      • 注意: 这里没有D没有自动生成移动赋值.

    • 智能移动并不都是移动,也有可能是拷贝.

  3. 影响

    • 互斥

      • 声明了移动的任意一个,不会生成另一个.

    • 原因

      • 声明了移动构造,说明默认的移动构造无法满足需求,可能有资源操作,编译器生成的也很可能满足不了.

      • 所以编译器就不自作主张的生成.

    • 来个案例

      #include<iostream>
      class T {
      public:
         T(){}
         ~T(){}
         T(T&&){}
      };
      
      int main() {
         T a,b;
         a = std::move(b);
      }
      
      • 编译报错,因为声明了移动构造,不会生成移动赋值.

    • copy影响移动move

      • 同理,默认copy无法满足,编译器认为copy涉及到资源操作,移动一个都不生成.

      • memberwise move可能用到copy.

    • move影响copy

      • 反过来也可以成立.

      • copy被声明为delete,也会参与匹配.

      • 默认move无法完成数据处理,那么默认copy很可能也不完成.

    • C++11move影响copy会影响到c++98的代码吗?

      • 不会,因为C++98没有移动语义.

      • 除非C++98的代码改成适配C++11的了,改了就应该都改.

  4. C++编译器演进

    • 三件套

      • 拷贝构造,拷贝赋值,析构.

      • 任意一个出现,一般都说明涉及到了资源分配.

      • 三者一般都是一起出现的.即定义一个,另外的也该定义.

    • C++98

      • 没有注意这茬,就允许出现了也可以自动生成.

      • C++11则改进了.

    • C++11

      • 理论上是三者一起出现的,声明一个,另外两个也该声明.

      • 声明析构还是会默认生成拷贝,因为不生成很多C++98代码会出问题.

      • 不过编译器给出了警告, 说在C++11中已经deprecated,虽然还会给你生成,但是建议自定义.

      • 析构和copy是共生的,那么间接的,有了析构就有了copy,有了copy就不会生成move.

    • 生成move的条件

      • copy

      • move

      • 无析构

    • 生成copy的条件

      • copy

      • move

      • 无析构

      • C++11为兼容C++98,允许生成copy,但是会警告.

  5. 使用默认

    • 核心

      • 有时候生成析构仅仅是为了输出.并不涉及到资源操作.

      • 那么自己实现就很麻烦.

      • 提供了=default,让编译器自动生成.

      • 省时省力.

    • 默认

      • 很多时候,默认都可以按照预期执行.

      • 有些时候声明=default可能多此一举,但是使得目的更明确,减小因为修改导致不再生成,导致编译报错的概率.

    • 小结

      • 默认构造:相同,无构造时.

      • 默认析构: 类似,c++11析构noexcept.

      • 拷贝构造: 行为一致,拷贝成员,没有才生成.c++11声明move,copy变成delete参与匹配.无拷贝赋值和析构时生成.

      • 拷贝赋值: 行为一致,拷贝成员,没有才生成.c++11声明move,copy变成delete参与匹配.无拷贝构造或析构时生成.

      • 移动构造:无拷贝,无移动,无析构定义,用时生成.智能移动,拷贝或移动.

      • 移动赋值:无拷贝,无移动,无析构定义,用时生成.智能移动,拷贝或赋值.

    • 成员模板

      • 模板不影响生成.因为编译器不考虑在内.

      • 在满足上面说的条件时,编译器仍然会生成,即特例化…而不是模板匹配.

      • 编译器默认>模板生成.

  6. 总结

    • 编译器按需生成,涉及资源操作就不尝试生成. 即自定义拷贝移动析构.

    • 默认移动是挨个std::move,具体类型的匹配函数可能是拷贝或移动.

    • 声明了move,copydelete,会参与匹配,然后报错.

    • 声明析构,也会生成copy,但是不推荐. 主要是向c++98兼容,建议用户自己实现.

    • 对拷贝移动进行模板化,不影响默认的函数生成.优先级高于模板.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11 类的六大基本成员函数默认生成,default字段的含义 的相关文章

  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • Python面向对象植物大战僵尸

    先来一波效果图 来看看如何设计游戏架构 import sys import pygame class BaseSprite pygame sprite Sprite def init self name super init self im
  • 七款简单易用的项目管理平台

    TeamLab 它是一个在线商业协作和项目管理的平台 主要功能包括 项目管理 里程碑管理 任务 报表 事件 博客 论坛 书签 Wiki 即时消息等 TeamLab是专为中小型企业 团队打造的系统 使用SaaS解决方案的网站 也就是说 您可以
  • 【持续更新之】CSS小技能

    empty 伪类 匹配空标签元素 例如 div class cs div cs empty width 120px height 120px border 10px dashed 此时 div元素就会匹配 empty伪类 用法 隐藏空元素
  • Aircrack-ng设置监听模式异常

    Aircrack ng设置监听模式异常 aircrack ng 在某些情况下 用户使用Aircrack ng工具集中的airmon ng命令 将无线网卡设置为监听模式时 会出现异常 如SIOCSIFFLA65 Name not unique
  • fiddler中设置Before断点修改请求

    Fiddler最强大的功能莫过于设置断点了 设置好断点后 你可以修改httpRequest的任何信息包括host cookie或者表单中的数据 设置断点有两种方法 第一种 打开Fiddler 点击Rules gt Automatic Bre
  • 一文搞懂MySQL架构设计,再也不用担心面试官问得太深

    很多开发同学对SQL优化如数家珍 却对MySQL架构一知半解 岂不是只见树叶 不见森林 终将陷入细节中不能自拔 今天就一块学习MySQL分层架构 深入了解MySQL底层实现原理 以及每层的作用 我们常见的SQL优化到底在哪一层做了优化 1
  • 西门子PLC1500大型程序fanuc机器人汽车焊装

    西门子PLC1500大型程序fanuc机器人汽车焊装 包括1台西门子1500PLC程序 2台触摸屏TP1500程序 9个智能远程终端ET200SP Profinet连接 15个Festo智能模块Profinet通讯 10台Fanuc发那科机
  • Python OpenCV学习总结Day 3.1 图像处理(上篇) 颜色处理与二值化,滤波去噪,形态学腐蚀膨胀,边缘检测

    目录 前言 Day3 1 OpenCV图像处理核心技术 上篇 颜色处理与二值化 颜色空间转换 阈值二值化 颜色阈值筛选 滤波去噪 形态学操作 腐蚀膨胀 开运算与闭运算 边缘检测 Sobel算子 Roberts算子 Prewitt算子 Can
  • FPGA功耗估计

    1 背景 quad 资源 速度 功耗是FPGA设计中的三大关键因素 温度与功耗成正相关性 功耗大必然会导致温度高 高温最常见的问题是系统重启 温度高对FPGA内部的时序不利 导致可靠性下降 2 功耗分类 1 芯片静态功耗 quad FPGA
  • Unity3D教程:fbx动画

    Unity3D教程fbx动画 在官方提供的例子 可以找到主角的fbx文件 将此文件放到自己的Assets文件夹下 Unity3D中的Project面板会将其刷新出来 但是如下图所示 动作信息是没有经过分割的 一定要注意 不要选择Hierar
  • line 1-19/19(END)怎么解决?

    在Linux中经常会遇到下图这种现象 其实这是一种很正常的现象 我们只需要按一下Q键就可以正常输入命令了
  • 笔记本电脑开启电脑卓越性能-将CPU拉到最满仅需一条指令

    在Windows的PowerShell工具组中运行下面代码 powercfg duplicatescheme e9a42b02 d5df 448d aa00 03f14749eb61 然后打开电源选项 就会看到比原来多出一个卓越性能选项 保
  • windows下各调试器条件断点实例

    0x00 前言 发现网上很多关于ollydbg和windbg的条件断点的设置是错误的 所以这里总结下 0x01 字符串条件断点 ollydbg unicode字符串 bp kernel32 CreateFileW UNICODE esp 4
  • SQL-labs的第34关——报错注入 宽字节注入(POST)

    1 尝试进行注入 输入语句 账号 1 密码 1 返回页面如下 发现该关还是会向危险字符自动添加斜杠 2 中和干扰符 输入语句 id 1 df 返回页面如下 我们发现无法中和反斜杠 3 使用burp工具进行注入 截取数据包 进行注入 输入语句
  • 列表和元组元素的增加

    对于列表 元素是可以改变的 可以直接用内置函数来实现 l t for i in range 50 l append i t i print l print t 元组元素可以拼接但是不能增删 对于元组 其元素是不可以直接增加 但是可以通过元组
  • 网络编程之基础与接口函数

    一 网络编程 1 网络基础 相关历史 第一阶段 ARPANET 阿帕网 是网络基础协议的雏形 第二阶段 第一份IP协议说明书 协议 两者之间需遵守的约定 第三阶段 TCP IP 网络程序框架 C S B S C S 表示客服端 服务器设计框
  • X86和X64运行环境下C++调用汇编函数源码和解释

    备注 这里给出的代码是在Win10系统中VS2022开发环境下编译测试通过的 X86环境下C 调用汇编函数 c 代码 include
  • 【以太网硬件十三】SGMII和1000base-X有什么异同?

    个人主页 highman110 作者简介 一名硬件工程师 持续学习 不断记录 保持思考 输出干货内容 目录 MII接口类型 MII GMII RGMII SGMII SGMII与1000base X的异同 通过前面的文章我们已经知道了100
  • 十分淫霸的Mooege&MadCow,你懂得。

    支持伟大的暴雪 支持正版 更支持热心的Mooege组织 Just can t waiting for it 纯粹为了体验 Contents hide 1 Must Have Requirements 2 Requirements 3 Qui
  • C++11 类的六大基本成员函数默认生成,default字段的含义

    总览 核心 编译器会为一个类按需自动生成成员函数 C 98 构造 析构 拷贝构造 拷贝赋值 C 11 有了右值 就多了两个 移动构造和移动赋值 功能 构造 无参构造 T 析构 调用成员变量析构 T 拷贝构造 同类型对象初始化 T a b a