c++查漏补缺
f905699146
这个作者很懒,什么都没留下…
展开
-
一个c/c++程序是怎么从代码到可执行文件的
我们以我们最初学到的“hello world”程序为例。这个程序在编译中是这样进行的,首先执行g++ helloworld.cpp命令得到a.out文件;执行./a.out命令就可以输出hello world!事实上执行g++ helloworld.cpp可以分为四个步骤,分别是预处理,编译,汇编,和链接,这就像一个被隐藏的过程,使用者可以通过简单的命令即可完成复杂的步骤。 一,预处理首先是源代码原创 2017-06-06 13:49:58 · 6299 阅读 · 0 评论 -
拷贝构造函数的陷阱
拷贝构造函数大家都比较熟悉,通俗讲就是传入一个对象,拷贝一份副本。#include<iostream>using namespace std;class CExample {public: int a,b,c; char *str;public: //构造函数 CExample(int tb) { a = tb; b =转载 2017-08-23 13:52:37 · 235 阅读 · 0 评论 -
c++多重继承的bug
一个例子:#include <iostream>using namespace std;class Base1{public: virtual void foo1() {};};class Base2{public: virtual void foo2() {};};class MI : public Base1, public Base2{public: vir转载 2017-08-23 15:38:23 · 284 阅读 · 0 评论 -
c++类型别名
1、类型别名定义 类型别名(type alias)是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。有两种方法可用于定义类型别名。 (1)传统的方法是使用关键字typedef:typedef double wages; //wages是double的同义词 typedef wages转载 2017-09-23 15:30:39 · 1576 阅读 · 0 评论 -
abort,exit,return 的区别
exit(): 在调用时,会做大部分清理工作,但是决不会销毁局部对象,因为没有stack unwinding。 会进行的清理工作包括:销毁所有static和global对象,清空所有缓冲区,关闭所有I/O通道。终止前会调用经由atexit()登录的函数,atexit如果抛出异常,则调用terminate()。 abort(): 调用时,不进行任何清理工作。直接终止程序。 retrun:原创 2017-09-01 10:30:21 · 461 阅读 · 0 评论 -
const 和 static的区别
static的作用:对变量:1.局部变量:在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。1)内存中的位置:静态存储区2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。注:当static用来修饰局部变量的时...转载 2018-09-12 13:34:54 · 3039 阅读 · 0 评论 -
#pragma once和#ifndef的区别
1)#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况2)#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。...转载 2018-09-12 14:21:16 · 622 阅读 · 0 评论 -
operator new和placement new的区别
new 关键字 (1)调用operator new分配足够的空间,并调用相关对象的构造函数 (2)不可以被重载operator new (1)只分配所要求的空间,不调用相关对象的构造函数。当无法满足所要求分配的空间时,则 ->如果有new_handler,则调用new_handler,否则 ->如果没要求不抛出异常(以nothrow参数表达...转载 2018-09-12 16:26:06 · 313 阅读 · 0 评论 -
在 C++ 中子类继承和调用父类的构造函数方法
1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法。 2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。 3. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数,则会调用父类的默认无参构造函数。 4. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构原创 2017-08-23 12:47:40 · 340 阅读 · 0 评论 -
setjmp 和 longjmp 函数使用详解
非局部跳转语句—setjmp和longjmp函数。非局部指的是,这不是由普通C语言goto,语句在一个函数内实施的跳转,而是在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。#include <setjmp.h>int setjmp(jmp_buf env);返回值:若直接调用则返回0,若从longjmp调用返回则返回非0值的longjmp中的val值void longjmp(jmp转载 2017-08-25 23:23:25 · 470 阅读 · 0 评论 -
unsigned int 和int 相加问题
今天下代码的时候遇到一个很有意思的情况,代码如下:#include<iostream>using namespace std;int main(){ unsigned int a=4; int b=-6; if(a+b>0) { cout<<"a+b为正"<<endl;; } else { cout<<"a原创 2017-06-17 22:37:03 · 693 阅读 · 0 评论 -
用c++实现一个二叉排序树
二叉排序树又称二叉查找树(Binary Search Tree)。其定义为:二叉排序树或者收空树,或者是满足如下性质的二叉树。 (1)若它的左子树非空,则左子树上所有节点的值均小于根节点的值。 (2)若它的右子树非空,则右子树上所有节点的值均大于根节点的值。 (3)左右子树本身又各是一颗二叉排序树。 二叉排序树数据结构如下://节点类定义class Node{ int dat原创 2017-06-19 00:06:45 · 1955 阅读 · 0 评论 -
string类的内部实现
string类的实现实现string类是一道常见初级c++程序员的面试题,下面来具体介绍实现过程。 已知string的原型代码如下。从下图程序可以看出,string类的底层是一个字符指针。class String{ public: String(const char *str=NULL); //普通构造函数 String(const Strin原创 2017-06-03 02:35:38 · 1344 阅读 · 0 评论 -
堆和栈的区别
由于堆和栈在c/c++程序中非常重要,这里总结一下堆栈之间的区别。 (1)申请方式不同。 1,栈:由系统自动分配。 2,堆:由程序员申请。c中用malloc函数,c++用new关键字。 (2)申请后系统的响应不同。 1,栈:只要栈的剩余空间大于所申请的空间,系统将自动为程序提供内存,否则报异常,提示栈溢出。 2,堆:操作系统有一个记录空闲内存地址的链表,当系统收到程序原创 2017-06-03 03:07:18 · 271 阅读 · 0 评论 -
vector的简单实现
#include<algorithm>#include<iostream>#include<assert.h>using namespace std;template<typename T>class myVector{ private: #define WALK_LENGTH 64 //myVector each time increase space le原创 2017-06-03 13:04:21 · 306 阅读 · 0 评论 -
c++中如何实现一个不能被继承的类
方法一:用单例模式,这里不做阐述。 方法二:c++11标准提供关键字final。 方法三:友元加虚继承,这篇文章重点介绍这个方法。声明一个类A,构造函数声明为private,在类中声明友元类Bclass A{ private: A(){}; friend class B;};我们在让B虚继承Aclass B:virtual原创 2017-06-03 21:21:31 · 530 阅读 · 0 评论 -
map容器安插的方式
1,运用value_type 为了避免隐式转换,可以用value_type明白传递正确的型别。value_type是容器本身提供的型别定义,如:std::map<std::string,float>coll;coll.insert(std::map<std::string,float>::value_type("otto",22.3));2,运用pair<>std::map<std::strin原创 2017-06-30 20:01:03 · 182 阅读 · 0 评论 -
stl容器中移出元素的正确做法
我们知道在移出元素时,指向当前的迭代器会失效,如果要移出多个元素时,可以使用这种方法。我们看下面这段代码:typedef std::map<std::string,float> StringFloatMap;StringFloatMap coll;StringFloatMap::iterator pos;for(pos=coll.begin();pos!=coll.end();++pos){原创 2017-06-30 20:30:37 · 283 阅读 · 0 评论 -
迭代器失效的场景
vector迭代器的失效的情况: 1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。 2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。 3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将转载 2017-06-26 16:23:56 · 841 阅读 · 0 评论 -
链接器如何识别重复模板实例
在两个cpp文件中都有一个相同的模板定义,并且都有相同实例,那么在main文件中调用这个实例会调用哪个模板实例呢?//文件名caller1.cpp#include<iostream>template<typename T>void func(T const &v){ std::cout<<"func1: "<<v<<std::endl;}void caller1(){原创 2017-06-26 18:16:55 · 244 阅读 · 0 评论