
C/C++基础知识点
描述CC++使用过程中需知的知识点。
恋喵大鲤鱼
一条不止于编码的鱼。
展开
-
C++函数申明对函数模板实例化的屏蔽
C++函数匹配顺序C++语言引入模板机制后,函数调用的情形显的比C语言要复杂。当发生一次函数调用时,如果存在多个同名函数,则C++编译器将按照如下的顺序寻找对应的函数定义。原创 2015-10-29 14:06:54 · 2477 阅读 · 0 评论 -
C++ 将模板申明为友元
严格来说,函数模板(类模板)是不能作为一个类的友元的,就像类模板之间不能发生继承关系一样。只有当函数模板(或类模板)被实例化之后生成模板函数(或模板类),该函数(或类)才能作为其他的类的友元。为了叙述的方便,我们也称一个函数模板(或类模板)是一个类或类模板的友元,其实真正的含义是函数模板(或类模板)被实例化后生成的模板函数(模板类)作为类(或模板原创 2015-10-29 17:13:22 · 2173 阅读 · 2 评论 -
C++ 抛出异常与传递参数的区别
代码便已运行环境:VS2012+Debug+Win321.C++异常处理基本格式C++的异常处理机制有3部分组成:try(检查),throw(抛出),catch(捕获)。把需要检查的语句放在try模块中,检查语句发生错误,throw抛出异常,发出错误信息,由catch来捕获异常信息,并加以处理。一般throw抛出的异常要和catch所捕获的异常类型所匹配。异常处理的一般格式为: try {原创 2015-11-29 13:26:51 · 3368 阅读 · 0 评论 -
C++ 抛出和接收异常的顺序
代码编译运行环境:VS2012+Debug+Win32异常(exception)是C++语言引入的错误处理机制。它 采用了统一的方式对程序的运行时错误进行处理,具有标准化、安全和高效的特点。C++为了实现异常处理,引入了三个关键字:try、throw、catch。异常由throw抛出,格式为throw[expression],由catch捕捉。Try语句块是可能抛出异常的语句块,它通常和一个或多个c原创 2015-12-01 20:46:02 · 3032 阅读 · 0 评论 -
C++ 栈展开如何防止内存泄露
在栈展开(stack unwinding)是指,如果在一个函数内部抛出异常,而此异常并未在该函数内部被捕捉,就将导致该函数的运行在抛出异常处结束,所有已经分配在栈上的局部变量都要被释放。如果被释放的变量中有指针,而该指针在此前已经用new运算申请了空间,就有可能导致内存泄露。因为栈展开的时候并不会自动对指针变量执行delete(或delete[])操作。因此,在有可能发生异常的函数中,可以利用“智能原创 2015-12-03 10:28:57 · 2427 阅读 · 0 评论 -
C++学习知识点
1. OOP面向对象程序设计的多态的理解答:多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。 C++中,实现多态有以下方法:虚函数,抽象类,重载,覆盖,模板。2.类的特征答:封装、继承和多态。3. C++与C#的区别(1)C++中类的申明时,不能给数据成员赋值,通常使用构造函数来完成。而C#可以。还有C++种成员函数原创 2016-01-06 17:35:24 · 1849 阅读 · 0 评论 -
C++对象产生和销毁的顺序
C++中,如果对象是用new操作生成的,那么它的空间被分配在堆(Heap)上,只有显示地调用delete(或delete[])才能调用对象的析构函数并释放对象的空间。那么,在程序的其他存储区(全局/静态存储区,stack区)上的对象是依据什么样的顺序产生和销毁的呢?原创 2015-10-27 15:15:44 · 5630 阅读 · 0 评论 -
C++ mutable 的用法
mutalbe的中文意思是“可变的,易变的”,是constant(即C++中的const)的反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量将永远处于可变的状态。mutable的作用有两点:原创 2015-08-27 17:12:54 · 4374 阅读 · 0 评论 -
C++ 作用域与生命周期
Pascal之父Nicklaus Wirth曾经提出一个公式,展示出了程序的本质:程序=算法+数据结构。后人又给出一个公式与之遥相呼应:软件=程序+文档。这两个公式可以简洁明了的为我们展示程序和软件的组成。程序的运行过程可以理解为算法对数据的加工过程,程序的运行的结果,就是算法加工数据产生的结果数据。算法描述的是对数据加工的步骤,对应于程序中的函数。数据结构描述的是数据在计算机中的组织结构,对应于程原创 2015-08-28 10:58:11 · 4611 阅读 · 0 评论 -
字符数组的初始化与赋值
字符数组的初始化方式变量的定义指的是:指明变量所属类型、变量名称、分配空间以及初始化其初始值的过程。可以看出,变量的初始化是变量的定义的一部分。除了const变量需要显示的初始化以外,如果变量定义的时候,不显示初始化,编译器会为变量以默认值进行初始化。变量的赋值和变量的初始化有着本质的区别,具体见我的另一篇博客:初始化那点小事。原创 2015-09-09 17:10:00 · 20285 阅读 · 0 评论 -
C++函数调用时堆栈的变化情况
函数的正常运行必然要利用堆栈,至少,函数的返回地址是保存在堆栈上的。函数一般要利用参数,而且内部也会用到局部变量,在对表达式进行求值时,编译器还会生成一些无名临时对象,这些对象都是存放在堆栈上的。下面以Visual C++编译器为例进行研究。原创 2015-10-22 22:29:49 · 4102 阅读 · 0 评论 -
C++如何禁止函数的传值调用
按照参数形式的不同,C++应该有三种函数调用方式:传值调用、引用调用和指针调用。对于基本数据类型的变量作为实参进行参数传递时,采用传值调用与引用调用和指针调用的效率相差不大。但是,对于类类型来说,传值调用和引用调用之间的区别很大,类对象的尺寸越大,这种差别越大。传值调用与后面两者的区别在于传值调用在进入函数体之前,会在栈上建立一个实参的副本,而引原创 2015-10-24 09:13:08 · 1958 阅读 · 0 评论 -
C++函数指针简介
1.函数指针简介1.1函数指针的用法简单回顾函数指针的用法。#include <iostream>using namespace std;int add(int i,int j){ return i+j;}int main(){ //用法一 int(*addP)(int,int)=add; int tmp=addP(2,3); //或者 //原创 2015-10-24 12:33:33 · 1717 阅读 · 0 评论 -
C++ delete的三种面貌
一般来说,使用new申请空间时,是从系统的“堆”(heap)中分配空间。申请所得的空间的位置时根据当时的内存的实际使用情况决定的。但是,在某些特殊情况下,可能需要在程序员指定的特定内存创建对象,这就是所谓的“定位放置new”(placement new)操作。定位放置new操作的语法形式不同于普通的new操作。例如,一般都用如下语句A* p=new A;申请空间,而定位放置new操作则使用如下语句A原创 2015-10-30 17:03:56 · 8234 阅读 · 2 评论 -
C++ 虚拟继承与虚基类
1.多重继承带来的问题C++虚拟继承一般发生在多重继承的情况下。C++允许一个类有多个父类,这样就形成多重继承。多重继承使得派生类与基类的关系变得更为复杂,其中一个容易出现问题是某个基类沿着不同的路径被派生类继承(即形成所谓“菱形继承”),从而导致一个派生类对象中存在同一个基类对象的多个拷贝。 多重继承带来同一个基类对象在派生类对象中存在多个拷贝的问题,考察如下代码。#include <iostr原创 2015-11-13 22:58:35 · 2111 阅读 · 0 评论 -
C++输入输出操作符重载
1. 输入输出操作符简介C++中输入操作符是>>,输出操作符是<<,又叫做流对象的“插入操作符”和“提取操作符“。其实这两个操作符最初是在C语言中用于整数的移位运算,到了C++中才利用操作符重载的技术将它们应用于输入、输出操作。2.重载的原因应用于基本类型的输入、输出操作都已经在C++标准库中定义好,没有必要重新定义,也不允许重新定义。而对于用户自定义类来说,如果想利用输入、输出操作符进行本类对象的原创 2015-11-18 09:35:23 · 3694 阅读 · 0 评论 -
C++赋值操作符重载
1.赋值操作符重载的原因赋值操作符是一个使用频率最高的操作之一,通常情况下它的意义十分明确,就是将两个同类型的变量的值从一端(右端)传到另一端(左端)。但在以下两种情况下,需要对赋值操作符进行重载。 一是赋值号两边的表达式类型不一样,且无法进行类型转换。 二是需要进行深拷贝。2. 赋值操作符重载的注意事项赋值操作符只能通过类的成员函数的形式重载。这就说明了,如果要将用户自定义类型的值传递给基本数原创 2015-11-21 18:32:57 · 2003 阅读 · 0 评论 -
C/C++ volatile
volatile是“易变的”、“不稳定”的意思。volatile是C/C++的一个较为少用的关键字,它用来解决变量在“共享”环境下容易出现的读取错误的问题。原创 2015-07-18 11:56:25 · 9680 阅读 · 9 评论 -
C++ IO 流简介
1.输入输出(IO)与流的概念输入输出(IO)是指计算机同任何外部设备之间的数据传递。常见的输入输出设备有文件、键盘、打印机、屏幕等。数据可以按记录(或称数据块)的方式传递,也可以 流的方式传递。所谓记录,是指有着内部结构的数据块。记录内部除了有需要处理的实际数据之外,还可能包含附加信息,这些附加信息通常是对本记录数据的描述。流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数原创 2015-11-22 13:50:46 · 2298 阅读 · 0 评论 -
C++ 控制对象的创建方式和数量
通常情况下,对象创建在堆上还是在栈上,创建多少个,这都是没有限制的。但是有时会遇到一些特殊需求。1.禁止创建栈对象禁止创建栈对象,意味着只能在堆上创建对象。创建栈对象时会移动栈顶指针以“挪出”适当大小的空间,然后在这个空间上直接调用类的构造函数以形成一个栈对象。而当栈对象生命周期结束,如栈对象所在函数返回时,会调用其析构函数释放这个对象,然后再调整栈顶指针收回那块栈内存。在这个过程中是不需要oper原创 2017-02-12 18:38:54 · 1451 阅读 · 0 评论 -
C++ 接口继承与实现继承的区别和选择
1.接口继承与实现继承的区别《Effective C++》条款三十四:区分接口继承和实现继承中介绍的比较啰嗦,概括地说需要理解三点: (1)纯虚函数只提供接口继承,但可以被实现; (2)虚函数既提供接口继承,也提供了一份默认实现,即也提供实现继承; (3)普通函数既提供接口继承,也提供实现继承。 这里假定讨论的成员函数都是public的。这里回顾一下这三类函数,如下:class BaseCl原创 2017-02-13 16:34:44 · 4769 阅读 · 0 评论 -
C++ 获取类成员虚函数地址
1.GCC平台GCC平台获取C++成员虚函数地址可使用如下方法[1]^{[1]}:class Base{ int i;public: virtual void f1(){ cout<<"Base's f1()"<<endl; }};Base b;void (Base::*mfp)() = &Base::f1;printf(&quo原创 2017-02-21 16:54:13 · 2482 阅读 · 5 评论 -
C/C++ 的全缓冲、行缓冲和无缓冲
1.简介基于流的操作最终会调用read或者write函数进行I/O操作。为了使程序的运行效率最高,流对象通常会提供缓冲区,以减少调用系统I/O库函数的次数。在Linux中,缓冲方式存在三种,分别是: (1)全缓冲。输入或输出缓冲区被填满,会进行实际I/O操作。其他情况,如强制刷新、进程结束也会进行实际I/O操作。对于读操作来说,当读入内容的字节数等于缓冲区大小或者文件已经到达结尾,或原创 2017-03-19 11:58:47 · 7788 阅读 · 1 评论 -
C++ 临时对象
C++中临时对象又称无名对象。临时对象主要出现在如下场景。1.建立一个没有命名的非堆(non-heap)对象,也就是无名对象时,会产生临时对象。 2.构造函数作为隐式类型转换函数时,会创建临时对象,以值的方式传递,用作实参传递给函数。原创 2015-05-11 23:20:41 · 7756 阅读 · 4 评论 -
C++ 申明与定义的区别
清楚明白声明与定义是一名合格的程序猿的基本要求。 C++编码过程中谈及“声明”和“定义”是因为我们要使用一个变量、类型(类、结构体、枚举、共用体)或者函数,因此有申明和定义变量、类型和函数之说。C/C++中,使用一个变量、类型或者函数必须先在使用前申明它。原创 2015-06-01 15:08:56 · 4050 阅读 · 6 评论 -
C++ 动态联编实现原理分析
代码编译运行环境:VS2012+Debug+Win32所谓动态联编,是指被调函数入口地址是在运行时、而不是在编译时决定的。C++语言利用动态联编来完成虚函数调用。C++标准并没有规定如何实现动态联编,但大多数的C++编译器都是通过虚指针(vptr)和虚函数表(vtable)来实现动态联编。 基本的思路是: (1)为每一个包含虚函数的类建立一个虚函数表,虚函数表的每一个表项存放的是个虚函数在内存中原创 2015-11-17 19:25:46 · 4671 阅读 · 4 评论 -
C/C++ sizeof(下)
sizeof作用于基本数据类型,在特定的平台和特定的编译中,结果是确定的,如果使用sizeof计算构造类型:结构体、联合体和类的大小时,情况稍微复杂一下。原创 2015-11-10 22:08:55 · 2540 阅读 · 1 评论 -
C/C++ const
const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂。const用于定义一个常变量(只读变量)。当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多。下面将从七个方面总结const的用法。1.const位置const位置较为灵活,一般来说,除了修饰一个类的成员函数外,const不会出现先一条语句的最后。示例如下:#include &amp;amp;amp;lt;iostream&amp;amp;amp;gt;using nam原创 2015-07-05 00:43:31 · 2958 阅读 · 4 评论 -
C++ 链式操作
什么是链式操作?链式操作是利用运算符进行的连续运算(操作),它的特点是在一条语句中出现两个或者两个以上相同的操作符,如连续的赋值操作、连续的输入操作、连续的输出操作、连续的相加操作等都是链式操作的例子。原创 2015-07-18 16:52:45 · 6119 阅读 · 0 评论 -
C++ 名字空间详解
名字空间的由来名字空间(namespace)是由标准C++引入的,是一种新的作用域级别。原来C++标识符的作用域分为三级:代码块({…}和函数体)、类域和全局作用域。如今,在类作用域和全局作用域之间,C++标准又添加了名字空间域这一个作用域级别。命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。原创 2015-08-29 18:45:25 · 9068 阅读 · 2 评论 -
C++ 数据类型
C++数据类型简介C++是一种强类型语言。C++程序中的任何变量(或函数)必须遵循“先说明后使用”的原则。定义数据类型有两个方面的作用:一是决定该类型的数据在内存中如何存储,二是决定可对该类型的数据进行哪些合法的运算。C++的数据类型分为基本数据类型和非基本数据类型。其中非基本数据类型称为复合数据类型或构造数据类型。原创 2015-08-28 09:10:02 · 3819 阅读 · 0 评论 -
C++引用计数(reference counting)技术简介(3)
1.将Reference Counting加到既有的Class要想将引用计数施加到现有的实值对象Widget上,按照前面讨论的,都需要修改Winget类的源代码。但是,有时程序库的内容不是我们呢可以修改的,又该如何做呢?如果令Widget继承自RCObject,我们必须增加一个RCWidget class给用户使用,这很像之前关于String/StringValue的讨论。RCWidget扮演Str原创 2016-02-02 19:12:48 · 1962 阅读 · 0 评论 -
C++ 引用计数技术简介(1)
1.引用计数的作用C++引用计数是C++为弥补没有垃圾回收机制而提出的内存管理的一个方法和技巧,它允许多个拥有共同值的对象共享同一个对象实体。C++的引用计数作为内存管理的方法和技术手段主要有一下两个作用。 (1)简化了堆对象(heap objects)的管理。 一个对象被从堆中分配出来之后,需要明确知道是谁拥有了这个对象,因为只有拥有这个对象的所有者才能够销毁它。但在实际使用过程中, 这个对象可原创 2016-01-31 11:21:26 · 4063 阅读 · 1 评论