c++
文章平均质量分 84
暮色_年华
这个作者很懒,什么都没留下…
展开
-
Modern Effective C++条款三十六:如果有异步的必要请指定std::launch::async
如果任务是在不同的线程上执行的,那么它可能会访问到该线程的thread_local 变量的不同实例,这可能导致意外的行为或错误。为了避免这些问题,如果你的任务逻辑中涉及 thread_local 变量,最好显式指定 std::launch::async 策略来确保任务始终在一个新的线程上异步执行,或者重构你的代码以避免对 thread_local 变量的依赖。(4) 影响 thread_local 变量:因为不知道哪个线程会执行任务,所以也就不知道哪个线程的 thread_local 变量会被访问。原创 2024-12-05 17:52:03 · 215 阅读 · 0 评论 -
Modern Effective C++条款三十五:优先考虑基于任务的编程而非基于线程的编程
它可以代表一个正在运行的软件线程,也可以是未关联任何线程的空句柄(如默认构造的std::thread)。访问底层线程API:当需要使用非常基础的线程功能或操作系统级别的特性(如线程优先级、亲和性等),std::thread提供的native_handle成员函数可以直接访问底层API,而std::future不具备这种能力。(1)线程限额:操作系统能够支持的线程数量是有限的。实现特殊线程技术:当需要使用C++并发API之外的技术(如未被支持的平台上的线程池)时,std::thread提供了更大的灵活性。原创 2024-12-05 17:25:11 · 468 阅读 · 0 评论 -
Modern Effective C++条款三十四:考虑lambda而非std::bind
当使用steady_clock::now() + 1h作为std::bind的一个参数时,这个表达式是在std::bind被调用的那一刻就被计算(即立即求值),而不是在最终调用setAlarm时计算。当执行 std::bind(&std::chrono::steady_clock::now)时,实际上在创建一个函数对象,不带任何参数,并且当这个函数对象被调用时,会调用 steady_clock::now() 来获取当前的时间点。在C++11中,std::bind可用于模拟移动捕获和创建多态函数对象。原创 2024-12-05 16:27:20 · 382 阅读 · 0 评论 -
Modern Effective C++ 条款32&33:使用初始化捕获来移动对象到闭包中 / 对auto&&形参使用decltype以std::forward它们
C++11闭包捕获机制仅支持按值或按引用捕获变量,这使得对于只能移动的对象(如std::unique_ptr或std::future)的处理变得困难。此外,对于复制开销高的对象,C++11无法直接实现更高效的移动语义来代替复制。C++14引入了初始化捕获(也称为通用lambda捕获),使得开发者可以将表达式的结果直接作为闭包的数据成员进行初始化,并且允许使用std::move将不可复制的对象移动到闭包中。这种新形式的捕获为开发者提供了更大的灵活性和效率。原创 2024-12-04 17:17:05 · 428 阅读 · 0 评论 -
Modern Effective C++ 条款三十一:避免使用默认捕获模式
因此,lambda表达式访问的局部变量在整个操作期间都是有效的,不存在悬空引用的风险。这种情况下,默认按引用捕获模式([&])是安全的,因为此时lambda表达式的生命周期与父函数中局部变量的生命周期是一致的。比如,如果一个变量是在lambda创建后很快就会销毁的局部变量,那么按值捕获可能是更好的选择,以确保lambda内部持有该变量的一个独立副本。默认按引用捕获模式可能会带来悬空引用的问题,而默认按值捕获模式也没有解决这个问题,还会让你以为你的闭包是独立的(事实上也不是独立的)。原创 2024-12-04 16:08:00 · 642 阅读 · 0 评论 -
Modern Effective C++ 条款二十九&三十:移动语义和完美转发失败的情况
告诉编译器某个实体(变量,函数,类等)的名称和类型,不为其分配存储空间。不仅告诉编译器实体的名称和类型,还为其分配存储空间,并可能提供初始化值或实现。static const 整型数据成员的特殊情况。对于static const整型数据成员,可以在类内部进行初始化,但这实际上是声明的一部分。编译器会将这个常量的值传播到所有使用它的地方,从而不需要为它分配实际的存储空间。原创 2024-12-03 11:29:21 · 764 阅读 · 0 评论 -
Modern Effective C++ 条款二十八:理解引用折叠
static_cast<Widget&&>(param) 将 param 转换为右值引用,即使 param在std::forward 内部是一个左值引用,但通过 static_cast<Widget&&>(param),它被转换为右值引用。但是编译器没有报错。存在两种类型的引用(左值和右值),所以有四种可能的引用组合(左值的左值,左值的右值,右值的右值,右值的左值)。T 是一个模板参数,std::remove_reference<T>::type 用来去除 T 中可能存在的引用类型,从而得到原始类型。原创 2024-12-02 15:45:00 · 630 阅读 · 0 评论 -
Modern Effective C++ 条款二十七:熟悉通用引用重载的替代方法
第一个构造函数接受std::string类型的参数,并使用std::move来转移所有权,允许编译器进行潜在的优化。std::is_integral<std::remove_reference_t<T>>::value 确保T不是整型。这个类型参数通常是一个std::true_type或std::false_type,是标准库提供的类型,用于表示布尔值。使用 std::is_base_of 和 std::is_integral,std::is_base_of 用于检查类型是否是 Person 或其派生类。原创 2024-12-02 13:53:14 · 691 阅读 · 0 评论 -
Modern Effective C++ 条款二十六:避免在通用引用上重载
如果用户尝试用非int类型的整数(例如short, long, std::size_t等)来创建Person对象,编译器会优先选择模板化的完美转发构造函数,而不是预期的int构造函数。因此,传递这些整数类型会导致调用模板构造函数,进而可能导致编译错误,因为std::string没有接受这些整数类型的构造函数。当调用logAndAdd并传入short类型的索引时,编译器会优先选择T&&版本的logAndAdd,因为short可以直接绑定到T&&上,而不需要转换。标签分派可以帮助编译器选择正确的构造函数实现。原创 2024-12-02 10:17:15 · 944 阅读 · 0 评论 -
Modern Effective C++ 条款二十五:对右值引用使用std::move,对通用引用使用std::forward
对于右值引用,同但在某些情况下,应该使用std::move_if_noexcept而不是std::move,以确保在移动构造函数不可用或抛出异常时仍能安全地进行拷贝。有一个形参,因此需要两种重载实现,但是对于有更多形参的函数,每个都可能是左值或右值,重载函数的数量几何式增长:n个参数的话,就要实现2^n种重载。当你有一个按值返回的函数,其中返回值绑定到一个右值引用上时,应该使用std::move来确保执行移动操作,从而提高效率。在按值返回的函数中使用std::move和std::forward。原创 2024-11-30 12:22:27 · 998 阅读 · 0 评论 -
Modern Effective C++ 条款二十四:区分通用引用与右值引用
Args&&... args 是一个通用引用,因为形式是 type&&,并且 Args 的类型会在每次调用时被推导。初始值决定引用类型:通用引用的初始值决定了它是左值引用还是右值引用。MyTemplateType 可以是任何类型,param 是一个通用引用,因为其形式是 type&&,并且 MyTemplateType 的类型会在调用时被推导。auto&& 声明的变量是通用引用,因为会发生类型推导,并且形式是 type&&。当 T&& 用在一个有类型推导的地方时,它被称为通用引用或转发引用。原创 2024-11-30 11:39:25 · 661 阅读 · 0 评论 -
Modern Effective C++ 条款二十三:理解std::move和std::forward
在模板函数 logAndProcess 中,如果不使用 std::forward<T>(param) 而直接使用 param,那么无论传递给 logAndProcess 的是左值还是右值,param 都会被视为左值。std::forward 是一个有条件的转换,只有当传递给它的参数是右值时,它才会将参数转换为右值引用。使用 std::forward 在模板中转发参数时,保持参数的原始值类别。(2)std::move 不保证移动:std::move 只是将对象转换为右值引用,但并不保证实际的移动会发生。原创 2024-11-30 10:50:19 · 972 阅读 · 0 评论 -
Modern Effective C++ 条款二十二:当使用Pimpl惯用法,请在实现文件中定义特殊成员函数
使用std::shared_ptr的差异:如果使用std::shared_ptr而不是std::unique_ptr,则不需要在头文件中声明析构函数,因为std::shared_ptr的删除器类型不是智能指针的一部分,因此它可以在不完整类型上工作。如果使用std::unique_ptr,需要显式地声明析构函数并在实现文件中定义它,以确保在销毁std::unique_ptr前Impl已被定义。由于std::unique_ptr的删除器类型是其一部分,编译器需要知道完整的类型信息来生成正确的删除代码。原创 2024-11-28 23:27:49 · 801 阅读 · 0 评论 -
Modern Effective C++条款二十一:优先考虑使用std::make_unique和std::make_shared,而非直接使用new
如果computePriority()抛出异常,由于std::make_shared已经成功创建了std::shared_ptr,并且这个智能指针已经开始管理Widget对象,所以在异常处理过程中,std::shared_ptr的析构函数会被调用,从而释放Widget对象占用的内存。对于大型对象,如果使用std::make_shared,则对象的内存会在最后一个std::shared_ptr和最后一个std::weak_ptr都被销毁后才释放。如果需要指定自定义删除器,则必须直接使用new。原创 2024-11-28 19:37:10 · 782 阅读 · 0 评论 -
Modern Effective C++ 条款二十:当std::shared_ptr可能悬空时使用std::weak_ptr
如果缓存直接使用std::shared_ptr来存储对象,那么即使所有客户端都释放了它们的std::shared_ptr,缓存中的std::shared_ptr仍然会保持对象的存活,导致内存泄漏。效率比较:std::shared_ptr和std::weak_ptr在大多数实现中具有相同的大小,因为它们都存储了一个指向控制块的指针。赋值:将一个std::weak_ptr赋值给另一个std::weak_ptr时,源std::weak_ptr的弱引用计数减少1,目标std::weak_ptr的弱引用计数增加1。原创 2024-11-28 14:06:40 · 589 阅读 · 0 评论 -
Modern Effecive C++ 条款十九:对于共享资源使用std::shared_ptr
如果Widget对象已经被std::shared_ptr管理,那么将this传递给emplace_back会创建一个新的std::shared_ptr,这可能导致多重控制块问题(即多个std::shared_ptr管理同一个对象)。引用计数本身是存储在独立于所管理对象的内存块中的。(2)独占资源:如果不需要共享所有权,使用 std::unique_ptr 更合适,因为它具有接近原始指针的性能,并且可以从 std::unique_ptr 转换为 std::shared_ptr,反之则不行。原创 2024-11-27 21:53:19 · 479 阅读 · 0 评论 -
Modern Effective C++ 条款十八:对于独占资源使用std::unique_ptr
拷贝一个std::unique_ptr是不允许的,因为如果你能拷贝一个std::unique_ptr,会得到指向相同内容的两个std::unique_ptr,每个都认为自己拥有(并且应当最后销毁)资源,销毁时就会出现重复销毁。推荐使用 std::array、std::vector 或 std::string。数组管理:std::unique_ptr<T[]>用于管理动态分配的数组,但通常建议使用std::array、std::vector或std::string等容器代替原始数组。模板参数包:Ts&&…原创 2024-11-27 20:15:55 · 1334 阅读 · 0 评论 -
Modern Effective C++ 条款16&17:确保const成员函数线程安全条款&&特殊成员函数的生成
如果类没有任何用户定义的拷贝或移动操作,并且没有用户定义的析构函数,那么编译器可以自动生成移动构造函数和移动赋值运算符。默认情况下,这两个函数都会执行逐成员的移动操作,即调用每个成员的移动构造函数或移动赋值运算符。如果要让旧的C++98代码支持移动语义,需要使用C++11标准,并在类中添加相应的移动构造函数和移动赋值运算符。,它们是非虚的,除非相关函数是在派生类中的析构函数,派生类继承了有虚析构函数的基类。移动操作仅在需要的时候生成,如果生成了,就会对类的non-static数据成员执行逐成员的移动。原创 2024-11-27 19:23:18 · 679 阅读 · 0 评论 -
Modern Effective C++ Item 14 如果函数不抛出异常请使用noexcept
例如,如果 std::vector 中的元素的析构函数抛出异常,可能会导致 std::vector 的析构函数无法正常完成,从而导致资源泄露。如果违反前置条件,函数的行为是未定义的。谨慎声明 noexcept,即使这些函数自然不会抛出异常,也应该谨慎声明为 noexcept,因为前置条件的检查可能需要抛出异常。对于严格契约的函数,即使它自然不会抛出异常,也应该谨慎声明 noexcept,因为前置条件的检查可能需要抛出异常。大多数函数是异常中立的,即它们自己不抛异常,但可能调用其他会抛异常的函数。原创 2024-11-23 16:16:01 · 546 阅读 · 0 评论 -
Modern Effective C++ item12&13 使用override&使用const_iterator
优先考虑 const_iterator而非 iterator:const_iterator 等价于指向常量的指针,不允许修改其指向的值。标准实践是能加上 const 就加上,防止意外修改数据。原创 2024-11-21 23:53:54 · 761 阅读 · 0 评论 -
Modern Effective C++ Item 11:优先考虑使用deleted函数而非使用未定义的私有声明
这种方法可以防止客户端调用这些函数,但如果在成员函数或友元函数中调用这些函数,会在链接时引发错误。C++11 使用 = delete 将这些函数标记为删除的函数。删除的函数不能以任何方式被调用,即使在成员函数或友元函数中调用也会在编译时失败。使用=delete可以禁止特定类型的函数调用,可以禁止特定类型的模板实例化,类内的模板函数特化,如果类内有一个模板函数,使用 = delete 可以在类外删除特定的模板实例。这是因为在类内不能给特化的成员模板函数指定不同的访问级别,而在类外删除这些函数不会有问题。原创 2024-11-21 13:30:31 · 770 阅读 · 0 评论 -
Modern Effective C++ Item 10:优先考虑限域enum而非未限域enum
C++已有的std::pair类型类似于一个二元组,可看作是std::tuple的一个特例,std::tuple也可看作是std::pair的泛化。std::pair的长度限制为2,而std::tuple的元素个数为0~任意个。std::tuple的一个常见用途是从一个函数返回多个值std::tuple中元素被紧密地存储的(位于连续的内存区域),而不是链式结构。可以将std::tuple看作一个“快速而随意”的数据结构,把它当作一个通用的结构体使用,但又不需要创建和获取结构体的特征,使得程序更加简洁。原创 2024-11-21 13:12:25 · 675 阅读 · 0 评论 -
Modern Effective C++item 9:优先考虑别名声明而非typedef
除了上面介绍的类型,type_traits 还有如 std::is_signed (检查类型是否有符号)、std::is_unsigned (检查类型是否无符号)、std::is_arithmetic ( 检查类型是否为算术类型(整数或浮点数))等基础核心类型。例如,std::is_integral 用于检查一个类型是否为整数类型,std::is_floating_point用于检查一个类型是否为浮点类型,std::is_base_of用于检查一个类型是否是另一个类型的基类等。原创 2024-11-21 12:23:28 · 464 阅读 · 0 评论 -
Modern Effective C++ Item 8:优先考虑nullptr而非0和NULL
在模板中,传递 0 或 NULL 会导致类型推导出整型,而不是指针类型。使用 nullptr 可以避免这些问题,因为 std::nullptr_t 可以隐式转换为任何指针类型,而不会导致类型错误。尽管 NULL 可以被定义为其他整型类型,但它的主要问题是它本质上仍然是一个整型,而不是指针类型。在 C++98 中,如果同时重载了指针和整型的函数,传递 0 或 NULL 会调用整型版本的函数,而不是指针版本的函数。0 的类型:在 C++ 中,字面值 0 默认是一个 int 类型,而不是指针类型。原创 2024-11-21 12:19:18 · 234 阅读 · 0 评论 -
Mordern Effective C++ Item 7:区别使用()和{}创建对象
(2)声明一个名为time_keeper的函数,该函数返回一个TimeKeeper类型的对象,并且有一个单一的(未命名的)参数,该参数的类型是一个(指向)不接受任何输入并返回Timer对象的函数。C++11使用统一初始化来整合这些混乱且不适于所有情景的初始化语法,统一初始化是指在任何涉及初始化的地方都使用单一的初始化语法。在变量声明的例子中,自C++11以来,首选的方法是使用统一(花括号)初始化。C++11对象初始化的语法有多种,初始化值要用圆括号()或者花括号{}括起来,或者放到等号"="的右边。原创 2024-11-19 22:01:32 · 573 阅读 · 0 评论 -
Modern Effective C++:Item 6 auto推导若非己愿,使用显式类型初始化惯用法
在运行时,std::vector<bool>::operator[]返回的std::vector<bool>::reference执行它支持的向bool的转型,在这个过程中指向std::vector<bool>的指针已经被解引用。对于d,类型并不是bool,而是一个vector<bool>中的一个内部类。其他的代理类则或多或少不可见,比如std::vector<bool>::reference就是不可见代理类的一个例子,还有它在std::bitset的胞弟std::bitset::reference。原创 2024-11-19 20:28:24 · 841 阅读 · 0 评论 -
Modern Effective C++ Item5 优先考虑auto而非显式类型声明
当使用auto关键字来声明一个变量以存储lambda表达式时,编译器可以直接为这个lambda表达式创建一个合适的类型,并且这个类型是专门为这个特定的lambda表达式定制的。按值捕获的变量会被复制到成员变量中,按引用捕获的变量会被绑定到成员引用上。中提到的IDE类型显示问题),在很多情况下,少量显示一个对象的类型对于知道对象的确切类型是有帮助的,这通常已经足够了。(1)唯一性:每次编写不同的lambda表达式,即使其逻辑看起来相同,编译器也会生成不同的匿名类,因此每个lambda都有自己的闭包类型。原创 2024-11-18 22:28:29 · 934 阅读 · 0 评论 -
Modern Effective C++:理解decltype
在这个模板中,我们不知道我们操纵的容器的类型是什么,那意味着我们同样不知道它使用的索引对象(index objects)的类型,对一个未知类型的对象使用传值通常会造成不必要的拷贝,对程序的性能有极大的影响,还会造成对象切片行为(参见。exp只是一个普通的表达式,它可以是任意复杂的形式,但必须保证exp的结果是有类型的,不能是void;(3)如果exp是一个左值,或被括号()包围,decltype(exp)的类型就是exp的引用,假设exp的类型为T,则decltype(exp)的类型为T&。原创 2024-11-16 16:58:01 · 648 阅读 · 0 评论 -
Modern Effective C++:理解auto类型推导
推导落入了这里发生的第二种类型推导——模板类型推导的范围。花括号中的值并不是同一种类。类型推导和模板类型推导有一个直接的映射关系。类型推导除了一个例外,其他情况都和模板类型推导一样。说明符代替指定类型说明符的好处,所以我们应该很乐意把上面声明中的。类型推导的大部分内容。模板类型推导包括模板,函数,形参,但。的类型说明符的不同特征,把模板类型推导分成三个部分来讨论。声明的变量使用花括号的语法进行初始化的时候,会推导出。作为类型说明符的变量声明中,类型说明符代替了。类型推导和模板类型推导唯一不同的地方。原创 2024-11-16 16:14:51 · 558 阅读 · 0 评论 -
Modern Effective C++:item 1 理解模板类型推导
当 T 是一个模板参数类型,并且T是推导出来的类型,T&&才是通用引用。T 是模板参数,ParamType 是函数参数的实际类型,它可能是 T 本身,也可能是对 T 进行了一些修饰后的类型(如 const T&、T* 等)。数组与指针形参这样的等价是C语言的产物,C++又是建立在C语言的基础上,它让人产生了一种数组和指针是等价的的错觉。ParamType 是函数参数的类型,它可以是 T 本身,也可以是对 T 进行了一些修饰后的类型,比如加上 const、&(引用)、*(指针)等。依赖于模板类型推导。原创 2024-11-15 23:52:00 · 1243 阅读 · 0 评论 -
More effective C++:杂项
在继承层次中,如果基类 Animal 有赋值操作符 operator=,而派生类 Lizard 和 Chicken 也有各自的赋值操作符,通过基类指针进行赋值时,只会调用基类的赋值操作符,导致部分赋值问题。结构兼容性:C++ 中的 struct 规则兼容 C 中的规则,因此相同的结构可以在 C++ 和 C 之间安全传递。(3)使用语言特性强制设计约束:利用C++的语言特性来实现设计意图,比如通过将某些成员函数声明为私有来防止不希望的操作,或者使用模板和泛型编程来提高代码的灵活性和复用性。原创 2024-11-15 19:30:51 · 663 阅读 · 0 评论 -
More Effective C++:技巧
虚拟构造函数并不是一个真正意义上的构造函数,而是一个设计模式。这种模式允许根据输入数据动态创建不同子类的对象。通常,这种函数是一个静态成员函数或全局函数,它能够根据输入数据确定应该创建哪个子类的对象,并返回该对象的指针或智能指针抽象基类 NLComponent:包含一个纯虚函数 clone,确保所有派生类都必须实现这个函数。提供了一个虚析构函数,确保派生类的对象在通过基类指针删除时能够正确析构。原创 2024-11-14 20:23:12 · 742 阅读 · 0 评论 -
More effective C++:效率(2)
避免临时对象:operator+ 和 operator- 通过创建临时对象来调用 operator+= 和 operator-=,但这仍然是一个高效的实现方式,因为临时对象的创建和销毁开销相对较小。代码复用:通过 operator+= 和 operator-= 来实现 operator+ 和 operator-,可以减少代码重复,只需要维护 operator+= 和 operator-=。效率:operator+= 和 operator-= 是赋值运算符,它们直接在左操作数上进行操作,不需要创建临时对象。原创 2024-11-13 22:32:42 · 747 阅读 · 0 评论 -
More effective C++:效率(1)
如果 field1Value 为 nullptr,表示 field1 尚未从数据库中读取,此时调用 fetchFromDatabase 方法从数据库中读取 field1 的值,并将其存储在 field1Value 指向的新分配的 std::string 对象中,返回field1Value 指向的 std::string 对象的引用。某些情况下,返回对象是不可避免的。常量版本:当读取 s2 的第一个字符时,调用的是常量版本的 operator[],不会创建独立的副本,直接返回共享数据中的字符引用。原创 2024-11-12 22:56:24 · 823 阅读 · 0 评论 -
More Effective C++:异常
强制性:异常不能被忽略,这与传统的错误代码不同,后者可能被忽略。安全性:异常确保了错误状态被正确处理,而非让程序继续运行在一个不确定的状态下。异常安全编程:异常安全的程序不是偶然形成的,而是通过精心设计得到的。就像一个多线程环境下的程序需要专门设计一样,异常安全的程序也需要特别考虑。(1)确保资源正确释放,即使在发生异常的情况下也是如此。(2)在异常被抛出后,程序应该能够保持一致的行为,即要么完全成功,要么完全回滚到之前的状态。原创 2024-11-11 22:36:37 · 1207 阅读 · 0 评论 -
More Effective C++:运算符
具体来说,当我们尝试比较数组a和数组b的一个元素b[5]时,如果写成了a == b[5],编译器可能会尝试将b[5](一个int)隐式转换为一个Array<int>对象,而这显然不是我们期望的行为。返回const对象是为了防止连续的后缀操作,如i++++,这会导致未定义行为,因为i++返回的是一个临时对象,不能再次进行自增操作。如果a的值为false,原本b不应该被计算,但现在b仍然会被计算。防止连续的后缀操作:如i++++,这会导致未定义行为,因为i++返回的是一个临时对象,不能再次进行自增操作。原创 2024-11-10 19:22:19 · 876 阅读 · 0 评论 -
More Effective C++:基础议题
指针定义:指针是一个变量,它存储的是另一个变量的内存地址。语法:通过*操作符来定义,并且可以通过->操作符来访问成员。灵活性:指针可以在任何时候被重新赋值,以指向不同的对象。空值:指针可以被设置为nullptr(或NULL/0),表示它不指向任何有效的对象。检查:在使用指针之前通常需要检查它是否为nullptr,以避免潜在的运行时错误。初始化:指针可以不初始化就声明,但这通常是不安全的做法。用途:当程序逻辑允许一个变量在某些情况下不指向任何东西,或者需要改变指向的对象时,使用指针是合适的。原创 2024-11-09 16:56:07 · 1043 阅读 · 0 评论 -
C++对象模型:站在对象模型的尖端
如果在 catch 块内部再次抛出异常(例如 throw或者 throw e),那么原始的异常对象会被复制,并且新的副本会被传递给下一个匹配的 catch 子句。如果catch子句中有throw语句来重新抛出异常,那么原来的异常对象会被复制,新的副本将被传递给下一个catch子句。当一个异常被抛出时,异常处理机制需要确定异常对象的实际类型,这样才能找到匹配的catch子句。此外局部对象 p 会在函数退出时自动销毁,但如果在 p 的构造过程中抛出异常,函数会直接退出,不会执行后续的代码。原创 2024-11-07 11:20:33 · 636 阅读 · 0 评论 -
C++对象模型:执行期语义学
可以自定义new和delete操作符来改变内存管理的行为,比如设置自己的内存分配策略或者错误处理机制。原创 2024-11-05 17:44:10 · 782 阅读 · 0 评论 -
C++对象模型:构造、析构、拷贝语意学
Point 类的声明public:private:Point类有三个私有成员变量 _x _y 和 _z,定义一个带有默认参数的构造函数,用于初始化Point对象。默认构造函数的行为当一个Point对象被声明但未显式初始化时,如全局变量Point global;,默认构造函数会被调用,初始化所有成员变量为0.0(默认构造函数是 Point,构造函数是一个带默认参数的构造函数,可以作为默认构造函数使用)。对于全局变量,其初始化会在程序启动时发生。显式初始化列表 vs. 构造函数内联扩展。原创 2024-11-04 12:54:31 · 786 阅读 · 0 评论
分享