c++ 编译期与运行期
c++ 编译期与运行期总结
一 见识编译期的力量
#include "stdafx.h"
#include <iostream>
using namespace std; class A{
public:
virtual void f(){ cout << "A" << endl; }
}; class B :public A
{
private:
void f(){ cout << "B" << endl; }
}; int _tmain(int argc, _TCHAR* argv[])
{
A *pA = new B();
pA->f(); return 0;
}
出现了很有趣的结果,在main函数中,访问到了B类中的私有方法。为什么会出现这样的结果呢?
一般来说外部对象访问类的私有成员,除非是友元,否则在编译的时候就会报错,但是上面那段代码却可以正常的编译通过。
C++因为支持面向对象编程,制订了一系列实现策略的语言机制。其中,各种各样的“限制”主要是出现在编译时:因此如果直接B d; d.f(); 就会导致编译错误:编译器发现
B::f()是B类的私有成员函数,因此拒绝这样的访问。
这里我们可以区分类和对象:类是编译期的概念,也是“访问权限”、“成员数据”、“成员函数”这几个概念的“作用域”。而对象的作用域是运行期。它包括类的实例、引用和指针。
A *pA = new B(); 这里 pA 是一个 A* , 所以就作为一个A类的指针参与了编译;
因此从pA调用f()在编译器眼中,就是调用了A类的公开成员函数f()因此通过编译;然后在运行时,由于多态作用pA调用的f()是派生类的f()成员函数。
虽然这时f()是private成员函数,但是由于 private/public 这些访问控制是编译时的限制,在运行时无效,所以B::f() 被成功调用。
如果能够理解这两个在不同时间作用的概念,这个问题就很好理解.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lusure/archive/2009/12/31/5113217.aspx
2 上面的例子是转载的,里面有个例子是输出调试信息的,
1)
const bool g_debug=1
void Log(char* str) {
if (g_debug){
printf(str);
}
}
2) #define DEBUG
#ifdef DEBUG
#define LOG(m) \
{\
printf(m);
\ }\
#else
#define LOG(m)
#endif
有经验的程序员肯定一眼就看出来第二种Log输出方式比较好。第一种的判断是在运行期,而第二种的判断是在编译期。第一种在每次运行log函数的时候都会去判断全局变量,
而第二种是在编译的时候就已经将不需要的Log信息定义为空。因为编译消耗的时间是一次性的,而运行的效率是直接呈现给用户的。由这种节约时间的方法,
我们可以发现把很多函数的判断和计算放在编译期,会大大节约运行的时间,提供运行效率,但是编译器并不是万能,所以编译期能做的工作还是十分的有限。
二 编译期 运行期 说明
1. 编译期是指把你的源程序交给编译器编译的过程,最终目的是得到obj文件,链接后生成可执行文件。 运行期指的是你将可执行文件交给操作系统(输入文件名,回车)执行、直到程序执行结束的期
执行的目的是为了实现程序的功能 2. 编译期分配内存,就是用静态或全局数组。这是在编译的时候确定的。
编译期内存错误,就是比如某个数据段DATA段或者CODE段等等,超过跑这个程序的目标机的存储器的限制。比如DOS下,DATA段不能超过64K吧。
运行期分配内存,就是用malloc()之类的函数,在堆上分配内存。 运行期内存错误,就是运行的时候发生的,比如申请不到内存,内存越界访问,等等。
除了内存外,编译器还做了宏替换,检查类型安全,上面一说的,类的“访问权限”、“成员数据”、“成员函数”这几个概念的“作用域”等等的语法检查,其他的我就不知道了。
三 编译期执行的效率
例子: http://qiezi.javaeye.com/blog/60067 编译期,把每一步操作结果的值都给缓存下来了,效率当然高了,我们使用相同的缓存策略也可以缩短函数的运行时间。
运行期执行的函数则没有这个优点,它和普通的函数没有区别,不同点在于它在编译的时候运行。把编译器看成一种动态语言运行环境,那么编译“编译期执行的函数”的过程就像是运行动态语言程序的过程。
如果程序中存在大量编译期执行函数,可能极大地降低编译效率,对于它的使用应该尽量避免。
模板提供的是一种声明式语法,在复杂的静态执行逻辑面前有时候会显得力不从心,编译期执行函数在解决这个问题的同时,却带来了上面这种副作用。
如果能把两者的优点结合起来用函数的语法来写程序,由编译器生成优化的模板代码,这种编译期执行才可以大量使用。
同样,可以写个梯乘的函数,求10000,在编译器和运行期,各写一个例子看看运行结果。就知道编译期做运算的好坏。
四 模板的运用 1 stl 模板是在编译期运行的,所以程序中尽量用stl,除了安全性与规范性好外,stl的一些操作都在编译时执行。
2 ATL ATL 跟com有个区别就是用了模板来取代com的虚拟表。ATL用了大量模板,很多操作都在编译时执行了, 所以编出来的可执行文件,比较小。这个是我自己猜的。
3 泛型编程语言,C++强大(但容易失控的)模板功能使它能在编译期完成许多工作,从而大大提高运行期效率。这个东西比较难,暂时没详细了解。一个不错 的例子:
http://wgysh1987.blog.163.com/blog/static/67986941200952454710401/
c++ 编译期与运行期的更多相关文章
- 深入分析Java的编译期与运行期
不知大家有没有思考过,当我们使用IDE写了一个Demo类,并执行main函数打印 hello world时都经历了哪些流程么? 想通过这篇文章来分析分析Java的执行流程,或者换句话说想聊聊Java的 ...
- Java编译期与运行期
编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程.在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本 ...
- constexpr:编译期与运行期之间的神秘关键字
Scott Meyers在effective modern c++中提到“If there were an award for the most confusing new word in C++11 ...
- c++ 之 编译期多态&运行期多态
编译时多态:程序运行前发生的事件 —— 函数重载.运算符重载 .模板 ——静态绑定 运行时多态:程序运行时发生的事件 —— 虚函数机制——动态绑定 template<typename T> ...
- 深入理解Java虚拟机读书笔记7----晚期(运行期)优化
七 晚期(运行期)优化 1 即时编译器(JIT编译器) ---当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为“热点代码”,包括被多次调用的方法和被多次执行的循环体. ...
- java在编译期和运行期都做了什么
Java对象内存存储,引用传递,值传递详细图解 java对象在内存中的分配 编译过程: 编译器把一种语言规范转化为另一种语言规范的这个过程需要哪些步骤?回答这个问题需要参照<编译原理>,总 ...
- Javac早期(编译期)
从Sun Javac的代码来看,编译过程大致可以分为3个过程: 解析与填充符号表过程. 插入式注解处理器的注解处理过程. 分析与字节码生成过程. Javac编译动作的入口是com.sun.tools. ...
- JVM总结(六):早期(编译期)优化
这节我们来总结一下JVM编译器优化问题. JVM编译器优化 Javac编译器 Javac的源码和调试 解析与填充符号表 注解处理器 语法分析与字节码生成 Java语法糖 泛型和类型擦除 自动装箱.拆箱 ...
- 深入理解JVM - 早期(编译期)优化
Java“编译期”是一段“不确定”的操作过程:可能是指一个前端编译器(编译器的前端)把*.java文件转变为*.class文件的过程:可能是指虚拟机的后端运行期编译器(JIT编译器,Just In T ...
随机推荐
- centos7安装mwget下载资源,提升下载速度
1.安装mwget wget http://jaist.dl.sourceforge.net/project/kmphpfm/mwget/0.1/mwget_0.1.0.orig.tar.bz2 ta ...
- ASP.NET Core多平台部署 (Windows Server+IIS与CentOS 7+Nginx)
一,Windows Server+IIS部署 1,安装配置IIS,这个应该都不用多说了,教程一堆 2,下载安装.NET Core Runtime 与 .NET Core SDK,下载请点击下载地址,如 ...
- GOF23设计模式之原型模式
GOF23设计模式之原型模式 1)通过 new 产生一个对象需要飞船繁琐的数据准备或访问权限,则可以使用原型模式. 2)就算 java 中的克隆技术,以某个对象为原型,复制出新的对象.显然,新的对象具 ...
- 学习EXTJS6(4)基本功能-信息提示框组件
1.使用组件,主要配置表现形式有二种(是否可以说参数) 用逗号分隔的传统参数列表方式: <script type="text/javascript"> Ext.onRe ...
- CentOS6.2上安装Oracle10g报ins_emdb.mk错误处理方法
oracle安装过程报ins_emdb.mk错误,此时继续点击“continue”即可,待Oracle完成安装后,再手工执行相应脚本完成链接即可 在CentOS6.2操作系统上,安装Oracle10g ...
- 洛谷 P3227 BZOJ 3144 [HNOI2013]切糕
题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案 ...
- 【ACM】hdu_1004_Let the Balloon Rise
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- POJ 1985
求一棵树内最远的两点,DFS,顺便记录以某节点为根内最远的两点的距离,返回最远点的距离.其实是DP. #include <cstdio> #include <iostream> ...
- 开启 J2EE(五)— Servlet之状态管理
HTTP无状态协议 首先我们要知道: HTTP协议是无状态协议. 我们知道HTTP协议就是server通过Request从浏览器接收和Response向浏览器输出的这么一个过程(浏览器和server的 ...
- 数据结构之---C语言实现共享栈
所谓共享栈是两个栈在一个顺序的存储空间中.两个栈的栈底各自是存储空间的首尾地址. 如图我们能够将两个栈构造成一个: 如图: 从这里也就能够分析出来,栈1为空时,就是top1等于-1时.而当top2等于 ...