blueyi's notes

Follow Excellence,Success will chase you!

1.首先明确当类中含有引用类型的成员变量时,编译器会将所有合成的默认构造函数都定义为delete,也就是说编译器将不会合成任何构造函数,所有构造函数必须由用户显式地定义,且该引用变量必须在所有定义的构造函数初始化列表中直接初始化,而不能在构造函数中初始化,形参也必须是引用类型。

Read more »

1.C++11中提供的tuple类型,即元组,该类型类似于pair类型,可以存放不同类型的变量,不同之处是它没有数量限制。该类型定义在头文件tuple中。

2.tuple类型支持常见的操作,如==!=get<i>(t);//获取t中第i个值等。

3.tuple中不但可以存储右值,而且可以存储左值。可以利用tuple让函数一次返回多个值。

Read more »

对SQL的了解一直就那几个语句,关键是那几个语句还经常记不清楚,虽然上过一次数据库的课,但并没有认真听,也没有系统的学习一遍SQL的基础知识,所以对于SQL,基本还处于完全陌生态。趁今晚的闲暇来系统的学习一下SQL相关知识(其实是因为今晚不想学习,权当休闲,哈哈)。
本文内容主要参考:

  • 《SQL必知必会》
  • 《MySQL必知必会》(后来发现有这本书,所以就补上了)

工欲善其事,必先利其器。为了方便后面练习,首先安装MySQL,这里只以Ubuntu下的安装为例

Read more »

本文所使用的环境:

  • Ubuntu-14.04 x64 kernel 4.2.0-36-generic
  • GCC version 4.8.4

需要用到的工具(都是系统自带的,以下是man的基本信息,详细信息可以直接查看man手册):

  • size - list section sizes and total size.可以列出section大小和总的大小,能够用于粗略估计,但不适合深度研究section大小
  • readelf - Displays information about ELF files.显示ELF文件的信息,readelf非常强大,能够显示出ELF非常多的信息
  • objdump - display information from object files. 显示object文件的信息,也就是目标文件,功能与readelf类似,但没有readelf强大,有些readelf可以显示的信息,它无法显示

如果对编译过程不甚了解,可以参看这里实例验证C/C++源代码如何变成程序的过程

Read more »

本来只是为了从底层了解下堆和栈的区别,以及heap和free-store的区别,结果便引出了从源代码编译开始,直到可执行程序如何加载到内存,以及C/C++内存布局的问题,这里做个总结,主要参考C++ Internals :: Memory Layout
本文所使用的环境:

  • Ubuntu-14.04 x64 kernel 4.2.0-36-generic
  • GCC version 4.8.4

需要使用的其他工具:

  • c++filt – Demangle C++ and Java symbols.详情可以自行查看man手册

C++编译器通常进行以下4个步骤将源代码编译为可执行程序:

  • 预处理器的预处理阶段,替换#开头的内容
  • 编译器编译阶段,将预处理后的源程序处理成汇编源程序
  • 汇编器的汇编阶段,将汇编源程序汇编为可重定位的目标二进制程序
  • 连接器将可生定位的目标程序连接成为可执行的二进制目标程序

以下面这段代码的编译链接过程举例:

Read more »

删除已经排好序的一维数组中的重复元素,要求时间复杂度为o(n)
方法:使用两个指针,指针front指向当前已经唯一化的最后一个位置,指针after向后遍历需要唯一化的元素,保证front之前的所有元素都始终是唯一的。
当front与after指向的值相同时,after向后移动,当不同时after值赋给front,且front也向后移动。
代码如下:

Read more »

C++中生成随机数即可以使用C语言中的rand和srand的方式,也可以使用C++11中的random类。

cstdlib中伪随机数

C语言中通过函数randsrand来产生伪随机数,这两个函数包含在头文件cstdlib中,其中srand用来产生设置随机数种子,rand每次返回一个当前的种子对应的随机数,这两个函数的声明如下:

1
2
void srand(unsigned seed);
int rand(void);

这两个函数的原型形如:

1
2
3
4
5
6
7
8
9
10
11
12
unsigned long int next = 1;
/* rand: return pseudo-random integer on 0..32767 */
int rand(void)
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
/* srand: set seed for rand() */
void srand(unsigned int seed)
{
next = seed;
}

显然rand只能生成整数,需要小数时,只需要跟一个浮点数进行除法即可
一个生成[1, 15]的随机数例子:

Read more »

项目中遇到过的C++问题

auto与const引用问题

1
2
3
error: invalid initialization of non-const reference of type 'std::_Rb_tree_const_iterator<std::pair<const std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> > >&' from an rvalue of type 'std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> > >}'
|| auto &valpair = con.find(valname[cont]);
|| ^

错误行处的代码应更正为auto valpair = con.find(valname[cont]);或者const auto &valpair = con.find(valname[cont]);
错误原因:
map的find成员函数返回的迭代器有可能是const,例如此处传递给函数的map是一个const引用,返回将是一个const的迭代器。而auto此时进行类型推断时,由于使用的是引用,所以auto默认推断的类型为非const的引用。根据修改的内容,显然当不是引用时,auto推断就是const的了;或者手动在auto前面添加一个const。(话说auto应该再智能一点)

Read more »

动态内存与智能指针

1.静态内存用来保存局部static对象,类static数据成员以及定义在任何函数之外的变量。static对象会在第一次使用前分配,程序结束时销毁。栈内存用来保存定义在函数内的非static对象。栈对象仅在其定义的程序块运行时才存在。分配在静态内存和栈内存中的对象由编译器自动创建和销毁。

Read more »
0%