![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
zpznba
日日行,不怕千万里。常常做,不怕千万事。
展开
-
如何利用VS查看C++类内存排布
书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承、虚函数存在的情况下。工欲善其事,必先利其器,我们先用好Visual Studio工具,像下面这样一步一步来:先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如...转载 2020-03-21 17:56:15 · 681 阅读 · 0 评论 -
C++智能指针之weak_ptr
weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对象的一个访问手段。weak_ptr是用来协助 shared_ptr 解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0...原创 2020-03-20 11:11:54 · 245 阅读 · 0 评论 -
C++的const和引用只能在初始化列表里初始化
class Book{public: Book( int s );private: int i; const int j; int &k;};//第一种Book::Book( int s ){ i = s; j = s; k = s;}//第二种Book::Book( int s ): i(s), j(s), k(s){}解释:第一种构造函数有错,而第...原创 2020-03-19 11:04:06 · 1524 阅读 · 2 评论 -
C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast
1. c强制转换与c++强制转换c语言强制类型转换主要用于基础的数据类型间的转换,语法为:(type-id)expression//转换格式1type-id(expression)//转换格式2c++除了能使用c语言的强制类型转换外,还新增了四种强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast,主要运用于继承...转载 2019-04-21 10:34:35 · 169 阅读 · 0 评论 -
聊聊map和vector的迭代器失效问题(某公司招聘笔试试题)
当删除一个STL容器(比如map, vector)中的某个元素时, 会引起迭代器失效, 所以, 我们务必提高警惕。 某次笔试, 我遇到这样一个题目: 删除map<int, int>中value为5的倍数的元素。 该题看起来很自然很简单, 实则有迭代器失效的陷阱。如果对迭代器失效问题一无所知, 则很容易写出如下的错误代码:#include <iostre...转载 2019-04-09 09:59:30 · 210 阅读 · 0 评论 -
C++ 中substr()的用法
string substr (size_t pos = 0, size_t len = npos) const;第一个参数是起始位置,第二个参数是切割长度,举个栗子:// string::substr#include <iostream>#include <string>int main (){ std::string str="We th...原创 2019-04-11 11:23:30 · 527 阅读 · 0 评论 -
std::string::npos的使用
std::string::nposstd::string::npos是一个常数,它等于size_type类型可以表示的最大值,用来表示一个不存在的位置,类型一般是std::container_type::size_type。定义static const size_type npos = -1;#include <iostream>int main(int argc, ...转载 2019-04-10 22:45:05 · 2484 阅读 · 0 评论 -
Effective_C++_条款十:令operator=返回对象的引用
为什么返回引用为了支持连锁赋值 返回引用可以节省资源,不必要为返回值调用构造函数了什么是连锁赋值int x,y,z;x = y = z = 5;这种赋值方式称为连锁赋值,它满足右结合律x = ( y = ( z = 5 ));赋值表达式z = 5执行后,将更新后的z值赋值给y,以此类推。自定义类型的连锁赋值Widget m;...Widget x, y,...原创 2019-03-23 22:33:39 · 225 阅读 · 0 评论 -
Effective_C++_条款九:绝不在构造和析构函数中调用virtual函数
避免在构造和析构函数中调用virtual函数切记:在基类构造期间,virtual函数会被当作普通函数调用class Base{public: Base() { VirtualFunction(); } virtual void VirtualFunction() ...原创 2019-03-23 22:20:43 · 86 阅读 · 0 评论 -
C++中的多态(动态多态)究竟是如何实现的?
#include <iostream>using namespace std; class E{public: // 为了方便叙述,故把公开a和b, 在实际系统中,很少这样做 int a; int b; virtual void f() { cout << "E::f" << endl; }; virtual...转载 2019-03-30 21:56:48 · 1321 阅读 · 0 评论 -
C++实现一个线程池
说明本线程池使用了互斥锁、条件变量、函数指针等常用工具。线程池的创建与执行threadpool_create创建线程池时,首先分配线程池数组和任务队列数组的空间,然后调用pthread_create创建线程,此时任务队列为空。 这样新创建的线程由于任务队列为空,所以都阻塞了。必须等待任务队列中有任务才能取执行。这部分实现使用条件变量。 当用threadpool_add添加很多任务后,每...原创 2019-04-21 11:16:17 · 863 阅读 · 1 评论 -
C++string类的简单实现
C++标准库中string类以类型的形式对字符串进行封装,使得它除了像一个存储字符的容器外,包含许多字符序列的处理操作。本文初步实现了以下函数:#include<iostream>#include<string.h>using namespace std;class Mystring;ostream& operator << (os...原创 2019-04-17 16:01:29 · 312 阅读 · 0 评论 -
反向迭代器(rbegin,rend)
C++ primer (中文版第四版)第273页9.3.2 begin和end成员 begin和end操作产生指向容器内第一个元素和最后一个元素的下一个位置的迭代器,如下所示。这两个迭代器通常用于标记包含容器中所有元素的迭代范围。c.begin() 返回一个迭代器,它指向容器c的第一个元素c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一个位置c.r...转载 2019-04-18 11:27:42 · 308 阅读 · 0 评论 -
c语言和c++中struct的区别
1. 虽然长的一样,但是本质上类型不同:C语言中:struct是用户自定义数据类型(UDT);C++中struct是抽象数据类型(ADT),所以下面代码:struct HE{ int a; };在C里面实际上数据类型为 (struct HE),所以定义一个结构HE变量都要 带上struct. structHE a; //C语言 变量方式 ...原创 2019-04-27 19:47:21 · 2344 阅读 · 0 评论 -
C++11 for循环新用法
c++11 for循环多了新的语法,下面用三种方法来遍历一个map:map<int, string> m;// 1. 用auto变量for (auto &v : m) { cout<<v.first<<" "<<v.second<<endl;}// 2. lambda表达式for_each(m.be...原创 2019-04-27 21:42:17 · 929 阅读 · 0 评论 -
用swap方法强行释放STL容器占用的内存
由于vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后erase掉后面9,999个,留下一个有效元素,但是内存占用仍为10,000个。所有内存空间是在vector析构时候才能被系统回收。empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存的回收。如果需要空间动态缩小,可以考虑使...原创 2019-04-27 22:25:25 · 232 阅读 · 0 评论 -
类成员函数指针和普通函数指针
前言:先声明一下,普通函数指针和类成员函数指针有很大的区别!所以在绑定函数的时候也会发生很多的不同的情况,本文就函数指针可能出现的各种情况一一进行分析。测试目录:1.普通函数指针指向普通函数2.普通函数指向非静态成员函数3. 类外部的 类函数指针 指向普通函数4. 类外部的 类函数指针 指向成员函数5. 类内部的 函数指针 指向成员函数 (类似于第2条)6. 类内部的 函数指...转载 2019-04-19 22:07:57 · 1531 阅读 · 0 评论 -
STL vector中的at方法
std::vector::at reference at (size_type n);const_reference at (size_type n) const;Access elementReturns a reference to the element at positionnin thevector.返回一个指向位置n的元素的引用。The func...原创 2019-04-29 10:54:19 · 2765 阅读 · 0 评论 -
C++11 新特性:Lambda 表达式
或许,Lambda 表达式算得上是 C++ 11 新增特性中最激动人心的一个。这个全新的特性听起来很深奥,但却是很多其他语言早已提供(比如 C#)或者即将提供(比如 Java)的。简而言之,Lambda 表达式就是用于创建匿名函数的。GCC 4.5.x 和 Microsoft Visual Studio 早已提供了对 lambda 表达式的支持。在 GCC 4.7 中,默认是不开启 C++ 11 ...转载 2019-04-29 17:01:04 · 158 阅读 · 0 评论 -
C++虚继承和虚基类详解
多继承(Multiple Inheritance)是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如典型的是菱形继承,如下图所示:图1:菱形继承...转载 2019-04-30 11:10:04 · 370 阅读 · 0 评论 -
C++虚函数与Object Slicing
在写MFC应用程序的时候,有必要搞懂虚函数和Object Slicing.我们首先来看一个极为简单的程序:#include <iostream>using namespace std; class A{public: void f() { cout << "A::f" << endl; g(); } void g()...转载 2019-03-30 21:17:04 · 143 阅读 · 0 评论 -
为什么C++中的析构函数通常要设为虚析构函数?
我们知道, C++中经常用到多态, 经常用基类指针指向派生类对象, 所以下面程序有bug:#include <iostream>using namespace std; class A{public: ~A() { cout << "A destructor" << endl; }}; class B : public A{p...原创 2019-03-30 17:31:46 · 252 阅读 · 0 评论 -
Effective C++条款五:C++默认编写了哪些函数
几乎每一个类都会用到构造、析构和赋值方法。C++默认编写了哪些函数拷贝构造函数 赋值操作符 析构函数 默认构造函数(如果你没有声明任何构造函数)编译器默默添加的这些函数都是public inline的。默认构造函数,有两个职责调用基类的构造函数 调用non-static成员变量的构造函数析构函数,也有两个职责调用基类的析构函数 调用non-static成员变量的析...原创 2019-03-14 08:37:21 · 116 阅读 · 0 评论 -
函数对象和函数适配器
函数对象一个行为类似函数的对象 可以没有参数,也可以带有若干参数 其功能是获取一个值,或者改变操作的状态。 例 普通函数就是函数对象 重载了“()”运算符的类的实例是函数对象 函数对象概念图例10-13、例10-14:使用两种方式定义表示乘法的函数对象 通过定义普通函数(例10-13) 通过重载类的“()”运算符(例10-14) 用到以下算法: ...原创 2019-02-12 16:10:29 · 188 阅读 · 0 评论 -
C++模板类实现栈(括号匹配问题)
题目描述栈的应用非常广泛。请先实现一个栈模板类(定义已在下面给出),然后利用这个栈类解决下面的问题:给定一个字符串,长度小于1000,其中只包含左右括号和大小写英文字母。请编写程序判断输入的字符串里的左右括号是否全部是匹配的,匹配规则即从内到外左括号都与其右边距离最近的右括号匹配。如匹配,输出“Yes”,否则,输出“No”。栈模板类定义如下:#include <iostream...原创 2019-02-08 21:52:57 · 701 阅读 · 1 评论 -
c++中关于模板的typename和class的区别
我们都知道,在STL中基本上都使用了模板类的声明,即template。在模板类的声明中,我们有两种方式:template <class T>template <typename T>在这里,class和typename是相同的。也就是说,在声明一个template type parameter(模板类型参数)的时候,class和typename意味着 完全相同的...原创 2019-02-08 20:34:46 · 825 阅读 · 0 评论 -
数组类模版的实现
数组类模板 静态数组是具有固定元素个数的群体,其中的元素可以通过下标直接访问。 缺点:大小在编译时就已经确定,在运行时无法修改。 动态数组由一系列位置连续的,任意数量相同类型的元素组成。 优点:其元素个数可在程序运行时改变。 vector就是用类模板实现的动态数组。 动态数组类模板程序#ifndef ARRAY_H#define ARRAY_H#in...原创 2019-02-07 20:16:22 · 807 阅读 · 0 评论 -
函数模版和类模版
函数模板思考:如果重载的函数,其解决问题的逻辑是一致的、函数体语句相同,只是处理的数据类型不同,那么写多个相同的函数体,是重复劳动,而且还可能因为代码的冗余造成不一致性。 解决:使用模板例:求绝对值函数的模板 函数模板定义语法 语法形式: template <模板参数表> 函数定义模板参数表的内容 类型参数:class(或typename) ...原创 2019-02-07 14:16:13 · 331 阅读 · 0 评论 -
C++ 多态性
多态的分类编译时多态:静态多态(函数重载,运算符重载)运行时多态:动态多态(虚函数)绑定:指把一个函数名和一个存储地址联系在一起的过程编译时多态是指绑定工作在编译阶段完成,运行时多态是指绑定工作在运行阶段完成。例如函数重载就是一种静态绑定,在编译阶段编译器就会根据每个函数的参数表来决定绑定哪个函数体。运算符重载两个对象,如两个复数类对象,用"+"、"-"符号,编译器是不...原创 2019-02-04 13:43:26 · 474 阅读 · 0 评论 -
《Effective C++》条款六 拒绝编译器自动生成的函数
如果类的每个对象都是独一无二的(《Effective C++》中所举的例子是地产中介商卖的房子),我们当然不希望类的对象之间存在拷贝构造和拷贝赋值操作:class HomeForSale{…}每个房子都是不一样的,所以希望这样:1 HomeForSale house1;2 HomeForSale house2;3 HomeForSale house3(house1); // ...原创 2019-03-14 09:24:08 · 132 阅读 · 0 评论 -
C++空类的大小
本文中所说是C++的空类是指这个类不带任何数据,即类中没有非静态(non-static)数据成员变量,没有虚函数(virtual function),也没有虚基类(virtual base class)。直观地看,空类对象不使用任何空间,因为没有任何隶属对象的数据需要存储。然而,C++标准规定,凡是一个独立的(非附属)对象都必须具有非零大小。换句话说,C++空类的大小不为0为了验证...原创 2019-03-14 22:53:48 · 491 阅读 · 0 评论 -
C++11中的数组初始化
定义:int *pia = new int[10]; // array of 10 uninitialized ints此new表达式分配了一个含有 10 个int型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了指针pia。在自由存储区中创建的数组对象是没有名字的,只能通过其地址间接地访问堆中的对象。注意:C++使用new和delete在堆(自由存储区)...原创 2019-03-15 09:59:16 · 4887 阅读 · 0 评论 -
易错题加深对C++多态的理解
#include <iostream>using namespace std;class A{public: virtual void x() { cout << "A::x" << endl; } void y() { x(); cout << "A::y" << endl; }};class...原创 2019-03-30 17:23:04 · 147 阅读 · 0 评论 -
C++函数中那些不可以被声明为虚函数的函数
1、顶层函数(普通函数):多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层函数不属于成员函数,是不能被继承的。2、构造函数:(1)构造函数不能被继承,因而不能声明为virtual函数。(2)反证法:调用构造函数后才能生成一个对象。假设构造函数是虚函数,那么它存在于虚函数表中,那么创建一个对象就需要而找到虚函数表去调用构造函数。这就需要去找到虚函数指针,而虚函数指针又...原创 2019-03-25 21:44:53 · 177 阅读 · 0 评论 -
C++ to_string的使用
举例:// to_string example#include <iostream> // std::cout#include <string> // std::string, std::to_stringint main (){ std::string pi = "pi is " + std::to_string(3.1415926)...原创 2019-03-18 11:49:30 · 5000 阅读 · 1 评论 -
字符串中单词逆序 && stringstream的简单使用
链接:https://www.nowcoder.com/questionTerminal/48b3cb4e3c694d9da5526e6255bb73c3来源:牛客网将一个英文语句以单词为单位逆序排放。例如“Iamaboy”,逆序排放后为“boyaamI”所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符输入描述:将一个英文语句以单词为单位逆序排放。...原创 2019-03-18 11:39:27 · 275 阅读 · 0 评论 -
C++中size_t 和 size_type的区别
为了使自己的程序有很好的移植性,c++程序员应该尽量使用size_t和size_type而不是int, unsigned1. size_t是全局定义的类型;size_type是STL类中定义的类型属性,用以保存任意string和vector类对象的长度2. string::size_type制类型一般就是unsignedint,但是不同机器环境长度可能不同win32和win64上...转载 2019-03-18 11:10:20 · 193 阅读 · 0 评论 -
C++中string::find()函数和string::npos函数的使用
1. string::find()函数 && string::npos函数介绍string::find()函数:是一个字符或字符串查找函数,该函数有唯一的返回类型,即string::size_type,即一个无符号整形类型,可能是整数也可能是长整数。如果查找成功,返回按照查找规则找到的第一个字符或者子串的位置;如果查找失败,返回string::npos,即-1(当然打印出的结果...原创 2019-03-18 11:01:26 · 227 阅读 · 0 评论 -
《Effective C++》条款七:为多态基类声明virtual析构函数
多态基类:顾名思义,是为了实现多态的基类。也就是说当一个类准备作为基类使用,且这个类中有虚函数的话,那么就应该给这个类加上虚析构函数。而非基类或者不用于多态的基类,就不要加。下面来具体分析一下:严格来说,多态分为编译时多态和运行时多态,编译时多态是函数的重载,而运行时多态则是迟绑定技术,即根据基类指针或引用的实际指向来决定采取何种行动,一般来说,多态特指运行时多态。下面我们来举有关C++多态的...原创 2019-03-15 14:44:03 · 213 阅读 · 0 评论 -
C++中引用不能重新赋值的理解
教材上说引用是不能重新赋值的,可是下面的程序能正常运行,不会出错。但怎么出现了引用赋值语句呢(语句[1])?是不是教材错了?原因究竟是什么呢?请看如下程序:#include<iostream.h>void main(){ int i=1,j=5; int& k=i; k=j; //语句[1] c...转载 2019-03-15 11:18:11 · 4656 阅读 · 3 评论