main与对象初始化 in C++
没有学过代码编译的原理,以前也没有兴趣去学编译器的相关原理,但是近期通过阅读google开源项目gtest,对我稍有触动。
代码:
main
test示例
TEST宏定义
#define TEST(test_case_name, test_name)\
GTEST_TEST_(test_case_name, test_name, \
::testing::Test, ::testing::internal::GetTestTypeId())
GTEST_TEST_宏定义:
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\
#test_case_name, #test_name, "", "", \
(parent_id), \
parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \
new ::testing::internal::TestFactoryImpl<\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
google通过一系列的宏和模板类实现了不同test的自动注册。run时一个一个调用test的run就行了。那么google是怎么实现调用前自动注册的呢?
设置两个断点:断点一、main;断点二、MakeAndRegisterTestInfo
运行顺序:
先运行到断点二
再运行到断点一
网上找到的解释:
对于全局对象(global object),VC下是先定义先初始化,但C++标准没做规定。全局对象默认是静态的,全局静态(static)对象必须在main()函数前已经被构造,告知编译器将变量存储在程序的静态存储区,由C++ 编译器startup代码实现。startup代码是更早于程序进入点(main 或WinMain)执行起来的代码,它能做些像函数库初始化、进程信息设立、I/O stream产生等等动作,以及对static对象的初始化动作(也就是调用其构造函数);在main()函数结束后调用它的析构函数。
C/C++程序的启动代码通常包含以下行为,并且按照所列的次序执行:
1、禁止所有中断。
2、从ROM 里复制所有初始化数据到RAM 里。
3、把未初始化数据区清零。
4、未堆栈分配空间并初始化。
5、初始化处理器堆栈指针。
6、创建并初始化堆。
7、(只对C++有效)对所有全局变量执行构造函数和初始化函数。
8、允许中断。
9、调用main。
注意点:
全局变量的初始化顺序是不确定的。
编译器不能定义不同编译单元全局变量的初始化顺序。
在同一个cpp文件里,编译器会保证按照他们出现的顺序初始化。但是如果两个全局变量在不同的编译单元,编译器不能控制他们的构造顺序,我们需要想办法确定他们的构造顺序。本人曾经因为这个问题导致过程序崩溃,所以记忆尤为深刻,在此特意提一下。
关于这一块的讨论,可以参考博文:http://blog.chinaunix.net/uid-26611383-id-3898563.html
main与对象初始化 in C++的更多相关文章
- Linq专题之对象初始化器
在C#3.0之前,如果创建一个新的对象,往往需要调用类的构造函数来初始化该对象的值,在c#3.0提供了一个"对象初始化器"的机制,使得开发人员在创建新的对象时不通过调用类的构造函数 ...
- Java对象初始化详解
在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Java如何执行对象的初始化做一个详细深入地介绍(与对象初始化相同,类在被加载之后也是需要初始化的,本 ...
- Java对象初始化详解(转)
在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Java如何执行对象的初始化做一个详细深入地介绍(与对象初始化相同,类在被加载之后也是需要初始化的,本 ...
- c#对象初始化
class test:IEquatable<test> { public int aa { get; set; } public string bb { get; set; } publi ...
- C#语法糖之第二篇: 参数默认值和命名参数 对象初始化器与集合初始化器
今天继续写上一篇文章C#4.0语法糖之第二篇,在开始今天的文章之前感谢各位园友的支持,通过昨天写的文章,今天有很多园友们也提出了文章中的一些不足,再次感谢这些关心我的园友,在以后些文章的过程中不断的完 ...
- Java父类子类的对象初始化过程
摘要 Java基本的对象初始化过程,子类的初始化,以及涉及到父类和子类的转化时可能引起混乱的情况. 1. 基本初始化过程: 对于一个简单类的初始化过程是: static 修饰的模块(static变量和 ...
- java 对象初始化和代码块初始化顺序
class A { public A(){ System.out.println("测试!!!!!!!!!!!"); } } class Demo19 extends A { { ...
- Java类和对象初始化
类的生命周期: Java类的初始化: 本阶段负责为类变量赋正确的初始值.(类变量即静态变量) Java编译器把所有的类变量初始化语句和静态初始化器通通收集到<clinit>方法中,该方法只 ...
- C++中的对象初始化
当对象在创建时获得了一个特定的值,我们说这个对象被初始化.初始化不是赋值,初始化的含义是创建变量赋予其一个初始值,而赋值的含义是把当前值擦除,而以一个新值来替代.对象初始化可以分为默认初始化.直接初始 ...
随机推荐
- UILabel的使用
UILabel是iOS用于显示文本的控件. 基本属性如下代码所示: UILabel *lbl = [[UILabel alloc] init] ; //设置显示区域 lbl.frame = CGRec ...
- iOS-浅谈runtime运行时机制
一.首先,从 runtime.h头文件中找到对 class 与 object 的定义 /// An opaque type that represents an Objective-C cla ...
- PLSQL转义字符
http://blog.csdn.net/cunxiyuan108/article/details/5800800
- 预处理语句--#define、#error和#warning
1.#define语句 我们经常会这样定义一些宏: #define BLOCK 8192 但这样的宏却不能在字符串中展开,如: printf("The BLOCK numb ...
- Quartz.NET管理周期性任务
Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和 ...
- AX Dynamic 2012 SSRS autorepot中取当前公司名、打印时间、打印页码
1. ssrs---取公司名称 =Microsoft.Dynamics.Framework.Reports.DataMethodUtility.PostDataMethodEvaluation(Mi ...
- xfce 双击窗口标题栏无法最大化解决办法
From: http://hi.baidu.com/jhang20081616/item/0b36ca1d2137df592b3e2219 0.前提是已经在window manager里设置了doub ...
- 在win server 2003上安装SQL Server 2008的步骤
1.安装Microsoft .NET Framework 3.5 Service Pack 1,下载地址:http://www.microsoft.com/zh-cn/download/confirm ...
- 使用PHP导入和导出CSV文件
我们先准备mysql数据表,假设项目中有一张记录学生信息的表student,并有id,name,sex,age分别记录学生的姓名.性别.年龄等信息. CREATE TABLE `student` ( ...
- VBS在指定范围内生成不重复的随机数
Dim Z()ReDim Z(15)For i=0 To UBound(Z) Z(i)=GetRndNum(i-1,UBound(Z)) WScript.Echo Z(i)Next Fun ...