当前位置:   article > 正文

【C++】总结8_去掉可执行文件中的debug信息可以减少内存占用吗

去掉可执行文件中的debug信息可以减少内存占用吗

strcpy和memcpy的区别

  • strcpy:

    • 函数原型:

      char* strcpy(char* destination, const char* source);
      
      • 1
    • 用途:strcpy 用于字符串的复制,它会自动复制整个字符串(包括"\0")。

    • strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束

    • strcpy 存在缓冲区溢出的风险,因为它不会检查目标缓冲区的大小,如果目标缓冲区不够大,可能导致内存越界

  • memcpy

    • 函数原型:

      void* memcpy(void* destination, const void* source, size_t num);
      
      • 1
    • 用途:memcpy 用于内存块的复制,即将一段内存块从源地址复制到目标地址,可以复制任意类型的数据,不限于字符串。

    • memcpy则是根据其第3个参数决定复制的长度

    • memcpy 需要提供目标缓冲区的大小(即复制的字节数),它不会自动添加 null 终止符,因此需要确保目标缓冲区足够大,以防止溢出。

  • 区别总结:

    • strcpy 用于字符串复制,自动复制整个字符串,需要注意目标缓冲区的大小。
    • memcpy 用于内存块复制,复制指定大小的内存块,不关心内容是否为字符串,不自动添加 null 终止符。

int main(int argc, char *argv[])

  • main函数是程序的入口点,也是程序开始执行的地方
  • int argc:代表命令行参数的个数(argument count),包括程序本身的名称。在执行程序时,可以通过命令行传递参数给程序。
  • char *argv[]:是一个字符指针数组(argument vector),用于存储命令行参数的值。每个元素都是一个指向字符串的指针,每个指针指向一个命令行参数的字符串,第一个参数为程序本身的名称

C++标准库

  • C++标准库是类库和函数的集合

  • C++标准库的特点:

    • C++标准库不是C++语言标准的一部分,由类库和函数库组成
    • C++标准库中定义的类和对象都位于std命名空间中
    • C++标准库的头文件都不带.h后缀
    • C++标准库涵盖了C库的功能
  • 函数:输入输出流库(iostream)、文件操作库(fstream)、字符串处理库(string)、时间日期库(chrono)、数学库(cmath)、随机数库(random)、动态分配等

  • 类:标准的 C++ I/O 类、String 类、数值类、STL 容器类、STL 算法、STL 函数对象、STL 迭代器、STL 分配器、本地化库、异常处理类、杂项支持库等

静态绑定和动态绑定

  • 静态绑定(Static Binding)和动态绑定(Dynamic Binding)用于在运行时决定调用哪个函数的实现,它们分别适用于静态多态(编译时多态)和动态多态(运行时多态)的情况
  • 静态绑定
    • 静态绑定发生在编译时,也称为早绑定或静态多态
    • 在静态绑定中,编译器在编译器阶段就确定了要调用哪个函数的实现,这是因为在编译时已经知道对象的类型
    • 静态绑定适用于非虚函数和全局函数,以及在不涉及继承和多态的情况下
    • 例如,如果有一个基类指针指向一个派生类对象,并通过该指针调用一个非虚函数,编译器会在编译时就确定调用基类的函数实现。
  • 动态绑定
    • 动态绑定发生在运行时,也称为晚绑定或动态多态
    • 在动态绑定中,函数调用的具体实现是在运行时通过对象的实际类型来确定的,而不是在编译时确定
    • 动态绑定适用于虚函数,通过基类的指针或引用调用虚函数时,会根据对象的实际类型来决定调用哪个函数实现
    • 例如,如果有一个基类指针指向一个派生类对象,并通过该指针调用一个虚函数,运行时会根据派生类的类型来确定调用派生类的函数实现

如何阻止一个类被实例化

  • 将类的构造函数声明为私有(private),有构造函数意味着该类不能在外部被直接实例化,只能在类的内部通过其他方法来创建对象。

    示例代码:

    class Singleton {
    public:
     // 公有的静态成员函数,用于获取类的唯一实例
     static Singleton& getInstance() {
         static Singleton instance; // 在静态成员函数中创建类的唯一实例
         return instance;
     }
    
     // 其他成员函数和数据成员...
    
    private:
     // 将构造函数声明为私有,防止类被实例化
     Singleton() {} // 可以是默认构造函数或其他自定义的构造函数
    
     // 其他私有成员函数和数据成员...
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在上述示例中,我们将 Singleton 类的构造函数声明为私有,这样外部代码无法直接创建 Singleton 对象。然后,我们在类的内部定义了一个公有的静态成员函数 getInstance(),用于返回类的唯一实例。这里采用了单例模式的设计,通过静态成员函数获取类的唯一实例,并确保只有一个对象被创建。

  • 将类定义为抽象基类

如何禁止程序自动生成拷贝构造函数?

  • 删除拷贝构造函数(C++11 及以上)

    在 C++11 及以上版本中,你可以通过在类的声明中使用 delete 关键字来删除拷贝构造函数和拷贝赋值函数。这样一来,编译器将禁止生成默认的拷贝构造函数,而在试图拷贝对象时会产生编译错误。

    class MyClass {
    public:
        // 删除拷贝构造函数
        MyClass(const MyClass&) = delete;
    
        // 其他成员函数和数据成员...
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 私有化拷贝构造函数

    某些情况下,为了避免调用拷贝构造函数和拷贝赋值函数,我们需要将他们设置成private,防止被调用。但是类的成员函数和friend函数还是可以调用private函数,如果这个private函数只声明不定义,则会产生一个连接错误。针对上述情况,可以定义一个base类,在base类中将拷贝构造函数和拷贝赋值函数设置成private,那么派生类中编译器将不会自动生成这两个函数,且由于base类中该函数是私有的,因此,派生类将阻止编译器执行相关的操作。

Debug和Release

  • 在软件开发中,Debug(调试)模式和 Release(发布)模式是两种常见的构建配置,用于在不同阶段的开发和部署中使用不同的编译选项和优化策略。

  • Debug 模式:

    • Debug 模式用于开发和调试阶段
    • 包含调试信息,所以容量比Release大很多,并且不进行任何优化,便于程序员调试
    • Debug模式下生成三个文件,除了.exe或.dll文件外,还有一个.pdb文件,该文件记录了代码中断点等调试信息
  • Release模式:

    • Release 模式用于发布和部署阶段
    • 编译器会进行各种优化,以提高程序的执行速度和减少内存占用。
    • 调试信息通常被移除,以减小可执行文件的大小,并降低潜在的安全风险。
    • Release模式下生成一个文件.exe或.dll文件
  • 通常在开发阶段,开发者会使用 Debug 模式来进行调试和测试,以便更容易地定位和解决问题。而在发布阶段,为了提高程序的性能和资源利用率,会使用 Release 模式来编译生成最终的可执行文件或库文件。

回调函数

  • 回调函数是一种常见的编程模式,回调函数就相当于一个中断处理函数,由系统在符合你设定的条件时自动调用。需要进行声明、定义和设置触发条件
  • 回调函数是由调用者(传递函数的地方)定义的,它通常包含特定的代码逻辑
  • 通过函数指针(回调函数名)作为参数传递回调函数的地址进行回调函数的调用
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/477986
推荐阅读
相关标签
  

闽ICP备14008679号