大学期间,学了一学期的C语言,当然包括学习数据结构时,用的也是C语言。当时刚刚接触计算机,对于编程更是一无所知。上课学习学习,偶尔会照着书上敲一下代码。大二下学期,就丢掉了不用了。最近由于工作的需要,要使用Java Native Interface,所以就学习了1天半的C++,对C++有了一点点的了解,写一下自己的理解。

一天半时间,也学不多少东西,我主要就搞明白了下面几个问题:

1)指针

  这么多年了,还记得在C语言时,最难以理解的,应该属于指针了。还记得谭浩强的那本C语言书(书名是啥,真的忘了。不过作者谭浩强老师,绝大多数的中国开发人员应该都知道的),前面大部分用的都是基本数据类型(也就是Java中的原生类型),后面一小部分突然讲起了指针,当时立马就 蒙 圈了。不过好在最后还是理解了指针,虽然后来又忘记了。

指针是什么?

指针是一个存放另外一个东西的地址的变量。指针是一个变量,把一个具有特殊作用的变量称为指针。它的特殊作用就是:存放另外一个东西的内存地址。也就是说指针变量的值代表了一个地址,这个地址是另外一个东西的。那另外一个东西是什么呢?就是我们说的对象(或者实例)。在C++中,还为这个对象起了一个别名:引用。

总结一下就是:指针变量指向一个对象(或者引用)。

*、&的使用

在声明语句中:

*表示声明的是指针,&表示引用。

这里说的声明语句,可以是变量声明,也可以是函数声明中。在函数声明中,返回值、函数名、参数都可以声明为指针。

在使用指针变量时,

(* 变量名)代表取对象。(& 引用)代表取指针。

void personTest(Person * p){
if(p!=NULL){
p->setAddress("Bei Jing, Hai Dian"); // 采用指针的方式赋值
(*p).setName("Fang JiNuo"); // 采用对象的方式赋值。
(*p).setAge();
printf("show info:\n%s\n", (*p).toString());
delete p;
p=NULL;
}
}

函数指针、指针函数

这个两个词八个字,不知道有多少人载了跟头,其实很好理解了。中国人说话,多以叙述的方式为主。这个两个词都是省略句,不过省略的是助词。

函数指针全名是:函数名是指针。

指针函数全名是:返回值是指针的函数。

这两个中,指针函数很容易理解了:

char * func(char[] p);这个函数就是一个指针函数。

函数指针,函数名是指针。指针也是变量,所以就可以理解为:函数名是变量。

下面是一个函数指针变量的声明:

typedef int (* func) (int x);

然后把这个变量作为另外一个函数的参数来使用:

typedef int (*func)(int arg); // 定义一个函数指针

/* 一个函数指针的实现
* funcImpl就可以作为func的值进行赋值。
*/
int funcImpl(int arg){
return arg;
} /*
* 声明一个函数,将函数指针作为函数call的参数
*/
void call(func f){
for(int i=; i<; i++){
cout << f(i) << endl;
}
} // 进行测试
int main(int argc, char* args[])
{
call(funcImpl);
}

程序执行结果是,打印出0到9。

这个函数指针与下面JavaScript的代码有同样的作用:

function funcImpl(int num){
return num;
}
(function call(f){
if(f){
if(f instanceof Function){
for(int i=0; i<10; i++){
alert(f(i));
}
}
}
})(funcImpl);

当然了与下面的Java代码代码也是一样的:

interface Callback{
int doCall(int num);
} static void call(Callback callback){
if(callback==null) return;
for(int i=0; i<10; i++){
System.out.println(callback.doCall(i));
}
} public static void main(string[] args ){
call(new Callback(){
public int doCall(int num){
return num;
}
});
}

在C#中,它还有另外一个名字,delegate。

其实它们都是传说中的钩子函数callback。

2)头文件、#include

在大学时,没有写过头文件,也没有看过头文件。所以头文件对我来说,一直是个谜。不过在学习了Java、C#后,就自然而然的会将#include 头文件理解为import、using等。

那么头文件中,会写什么呢?

一般来说,会将声明(类中的字段、方法的声明)写在.h文件中,将方法的实现,写在cpp文件中。以此来达到接口与实现的分离。其他地方使用#include时,就只会看到.h文件中的声明,看不到具体的实现。

另外要说的是#include的两种方式。 例如#include <xxxx.h>、#include “xxxx.h”。这两种方式,还是有区别的,<>方式是先从系统目录下找.h文件,” ”则是先从用户目录下去找.h文件。有点类似于Java中ClassLoader了,默认采用委托加载,也可以使用子类优先方式进行加载。

创建实例与回收

在C语言中,声明一个变量,可以直接使用声明的方式、也可以使用malloc的方式。

在C++中,又加入了一种new的方式,这种方式的写法与Java中是一样的。

创建

释放

声明(隐式):创建的是对象本身,而不是指针

隐式释放,不需要通过写代码。因为声明的对象在栈内,出栈后自动释放

malloc(显示):该方法用于分配内存,返回值是指针

使用free()进行释放

new :分配内存,返回值是指针

使用delete 进行释放

Malloc、new 分配内存后,返回值都是指针。且分配在内存中Heap区,不会自动释放,所以需要使用free、delete进行释放。

另外在使用feee、delete后,最好是将指针的值设置为NULL, 因为free、delete只是释放了对象占用的内存空间,而指针的值仍然是对象在被释放前占用空间的首地址。

这与Java是不同的,Java能够自动的进行回收。对象设置为null即可。Java中的回收机制是:采用分代回收算法对于不可达的对象进行回收。

void fun(){
Menu* m1=new Menu(); // 显式声明对象
Menu m2; // 隐式声明对象
this->menulist->push_back(m1);
this->menulist->push_back(&m2);
} void showList(){
list<Menu*>::iterator iter=this->menulist->begin();
while(iter!=this->menulist->end()){
Menu* menu=*iter;
cout << m->toString() << endl;
iter++;
}
}

这段代码,在编译时,是没有问题的,也就是说从写法来讲,没有错误的。但是在执行showList()时就会出现空指针异常。原因如下:

在fun()中,创建的m1在heap中,不会自动的释放,创建的m2,在stack中,会自动的释放,当fun执行完毕时m2对象实际已经不存在了。然后执行showList()时,变量到m2对象时,肯定空的了,list中存储的m2的指针,已经成为野指针了。

3)namespace

命名空间,在大多数语言中都有的。他们的作用都是为了区分。

//定义命名空间

namespace ns{

// your code

}

// 导入命名空间:

using namespace std;

// 使用命名空间:

std::xxxx

4)#define 、typedef

typeof 是为已有类型取别名。在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。

#define是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

5)操作符重载

学习C#时,知道可以对已有操作符进行重组,也就是赋予操作法新的功能。但是在C#中,我们很少这么做。Java中虽然没有语言级别的支持,但是Java中字符串拼接使用的+,其实就可以看做是操作符的重载。

在了解到C++中有操作符重载后,哦,原来这一点,C#是借鉴C++的呀。另外C#中还保留了struct。说到struct,再提一点,struct完全可以理解为C语言中的类。

C++ 中则使用了大量的操作符重载。具体的怎么去定义操作符重载,用到的时候再说吧。

  一天半时间,了解的东西真的不多,都是最基本的。虽然我也知道C++中的字符串拼接没有Java、JavaScript那么随意那么任性。但是这些不属于难点,所以我认为不需要再提了。

  最后,开一个玩笑,不懂JavaScript的Java程序员不是一个好的C++程序员。不懂Java的JavaScript程序员也不是一个好的C++程序员。

C++: 主要知识点的更多相关文章

  1. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  2. ASP.NET MVC开发:Web项目开发必备知识点

    最近加班加点完成一个Web项目,使用Asp.net MVC开发.很久以前接触的Asp.net开发还是Aspx形式,什么Razor引擎,什么MVC还是这次开发才明白,可以算是新手. 对新手而言,那进行A ...

  3. UWP开发必备以及常用知识点总结

    一直在学UWP,一直在写Code,自己到达了什么水平?还有多少东西需要学习才能独挡一面?我想对刚接触UWP的开发者都有这种困惑,偶尔停下来总结分析一下还是很有收获的! 以下内容是自己开发中经常遇到的一 ...

  4. C#高级知识点&(ABP框架理论学习高级篇)——白金版

    前言摘要 很早以前就有要写ABP高级系列教程的计划了,但是迟迟到现在这个高级理论系列才和大家见面.其实这篇博客很早就着手写了,只是楼主一直写写停停.看看下图,就知道这篇博客的生产日期了,谁知它的出厂日 ...

  5. lucene 基础知识点

    部分知识点的梳理,参考<lucene实战>及网络资料 1.基本概念 lucence 可以认为分为两大组件: 1)索引组件 a.内容获取:即将原始的内容材料,可以是数据库.网站(爬虫).文本 ...

  6. DoraCMS 源码知识点备注

    项目需要研究了下DoraCMS这款开源CMS,真心做的不错:).用的框架是常用的express 4 + mongoose,代码也很规范,值得学习. 源码中一些涉及到的小知识点备注下: https:// ...

  7. atitit 商业项目常用模块技术知识点 v3 qc29

    atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...

  8. HTML5知识点总结

    HTML5知识点总结(一) 一.HTML新增元素 1.IE9版本以下支持HTML5的方法 <!--[if lt IE9]> <script src="http://cdn. ...

  9. JavaScript易错知识点整理

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...

  10. Sqlserver中一直在用又经常被忽略的知识点一

    已经有快2个月没有更新博客了,实在是因为最近发生了太多的事情,辞了工作,在湘雅医院待了一个多月,然后又新换了工作...... 在平时的工作中,Sqlserver中许多知识点是经常用到的,但是有时候我们 ...

随机推荐

  1. M端总结

    最近在项目开发过程中涉及到了移动端,现在对此进行总结. 在此次M端的开发过程中,遇到了许多问题,在此进行一次总结,希望大家在以后的开发过程中能尽量规避类似的问题,提高开发效率和代码质量.一.布局1.移 ...

  2. 【SQLServer】DBHelper即C#数据库底层封装

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...

  3. 1Z0-053 争议题目解析702

    1Z0-053 争议题目解析702 考试科目:1Z0-053 题库版本:V13.02 题库中原题为: 702.View the Exhibit and examine the parameter se ...

  4. js作用域和变量提升

    Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of ...

  5. Hive UDF初探

    1. 引言 在前一篇中,解决了Hive表中复杂数据结构平铺化以导入Kylin的问题,但是平铺之后计算广告日志的曝光PV是翻倍的,因为一个用户对应于多个标签.所以,为了计算曝光PV,我们得另外创建视图. ...

  6. 创建自己的Vagrant box

    这是一个关于Vagrant的学习系列,包含如下文章: Vagrant入门 创建自己的Vagrant box 用Vagrant搭建Jenkins构建环境 用Vagrant和Ansible搭建持续交付平台 ...

  7. 多步骤多分步的组件StepJump

    最近的工作在做一个多步骤多分步的表单页面,这个多步骤多分步的意思是说这个页面的业务是分多个步骤完成的,每个步骤可能又分多个小步骤来处理,大步骤之间,以及小步骤之间都是一种顺序发生的业务关系.起初以为这 ...

  8. Nancy之Pipelines三兄弟(Before After OnError)

    一.简单描述 Before:如果返回null,拦截器将主动权转给路由:如果返回Response对象,则路由不起作用. After : 没有返回值,可以在这里修改或替换当前的Response. OnEr ...

  9. EF Fluent API上

     什么是Fluent API? 官方答案:EF 中内嵌的约定将 POCO 类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方 ...

  10. 图解DataGridView编辑列

    WinForm中DataGridView功能强大,除了可以自动绑定数据源外,还可以根据需求编辑列.下面以截图说明添加编辑列的步骤(HoverTreeSCJ 项目实际界面). 1.选择DataGridV ...