《深度探索C++对象模型》读书笔记(6)
一般而言,我们会把object尽可能放置在使用它的那个程序区段附近,这样做可以节省不必要的对象产生操作和销毁操作。 全局对象的静态初始化策略包括以下几个步骤: (1)为每一个需要静态初始化的对象产生一个_sti_……()函数,内含必要的constructor调用操作或inline expansions; (2)为每一个需要静态的内存释放操作的对象产生一个_std_……()函数,内含必要的destructor调用操作或inline expansions; (3)在main()函数的首尾分别添加一个_mai...
《深度探索C++对象模型》读书笔记(5)
在设计抽象基类时,需要注意以下几点: (1)不要将destructor声明为pure virtual function; 如果将destructor声明为pure virtual function,则设计者一定得定义它。因为每一个derived class destructor会被编译器加以扩展,以静态调用得方式调用其“每一个virtual base class...
《深度探索C++对象模型》读书笔记(1)
在C++中,有两种class data members:static和nonstatic,以及三种class member functions:static、nonstatic和virtual.已知下面这个class Point声明: class Point ...{ public: Point(float xval); virtual ~Point(); float x() const; static int PointCount(); protected: virtual ostream print...
C++中用户定义的转换
看到《深度探索C++对象模型》的第21页,在其谈到C struct在C++中的一个合理用途时,看到了C++中用户定义的转换的运用。因而回头将《C++ Primer》中关于用户定义的转换的一些细节温习了一下。 (1)用户定义的转换的必要性: 我们希望能够在SmallInt对象和其他SmallInt对象或者内置算术类型的对象之间进行加减操作,我们要通过提供6个SmallInt操作符函数来实现对这些操作的支持: class SmallInt ...{ friend operator+( const Small...
C++中的类静态成员和静态成员函数
今天刚开始看《深度探索C++对象模型》,刚看到第一章,竟然发现自己对类静态成员和静态成员函数还不够了解。查看了《C++ Primer》后,有以下几点体会: (1)为什么需要类静态成员? 有时候某个类的多个对象需要访问一个全局对象,在这种情况下“提供一个全局对象”比“每个类都维持一个独立的数据成员”要更为有效。而类静态成员与全局变量相比,又有两点好处:(a)不存在与程序中其他全局名字冲突的可能性;(b)可设置为private,实现信息隐藏。 (2)类静态成员的特点 对于非静态数据成员,每个类对象都有自己的...
谈论:C和C++哪个难?
这是我2008年1月8日发表在校内里的一篇文章: “C和C++哪个难?”这个问题在还没有学习这两门语言的时候我就跟同学讨论过了,当时只是道听途说,没有什么亲身体会。但是当时对于这个问题的确很疑惑。 如今我基本掌握了C和C++,接触过一些C的高级编程,也使用过C++的标准模板库(STL),目前正在研究C#(所谓的C++++),回过头来想想这个问题,有了自己的体会和感受,也有了几分资格讨论这个话题了。 C和C++哪个难?我对这个问题的回答是C++学起来难,但是用起来简单。 我个人认为C语言里就两个核心的东西...
C++中的延时函数
1.推荐用Sleep(); MS VC++可以用MFC的Sleep函数,参数是毫秒。 包含在头文件windows.h里 /*#includeiostream #includewindows.h using namespace std; void main () { Sleep(1000); //延时1秒 cout"adsd"endl; Sleep(10000); // 注意S大写 cout"123"endl; } */ 2.delay(); delay函数要自己写,编译器里没有。 #include ti...
C++对象布局及多态实现的探索(十二)
后记 结合前面的讨论,我们可以看到,只要牵涉到了虚继承,在访问父类的成员变量时生成的代码相当的低效,需要通过很多间接的计算来定位成员变量的地址。在指针类型转换,动态转型,及虚函数调用时,也需要生成很多额外的代码来调整this指针。象前一篇中对C170对象的obj.foo()和obj.f170()两次调用,传递到两个函数中的this指针居然是不一样的。 前面我们碰到过的怪异行为还有很多,比如偏移值指针指向地址的前4字节,及C150、C170对象中的4字节0值的语义,为什么对C150和C170调用foo函数...
C++对象布局及多态实现的探索(十一)
菱形结构的虚继承(3) 最后我们看看,如果在上篇例子的基础上,子类及左、右父类都各自定义了自己的虚函数,这时的情况又会怎样。 struct C140 : public virtual C041 { C140() : c_(0x02) {} virtual void foo() { c_ = 0x11; } char c_; }; struct C160 : public virtual C041 { C160() : c_(0x02) {} virtual void foo() { c_ = 0x12;...
C++对象布局及多态实现的探索(十)
菱形结构的虚继承(2) 我们再看一个例子,这个例子的继承结构和上一篇中是一样的,也是菱形结构。不同的是,每一个类都重写了顶层类声明的虚函数。代码如下: struct C041 { C041() : c_(0x01) {} virtual void foo() { c_ = 0x02; } char c_; }; struct C140 : public virtual C041 { C140() : c_(0x02) {} virtual void foo() { c_ = 0x11; } char c...
C++指针探讨 (一)数据指针
指针,在C/C++语言中一直是很受宠的;几乎找不到一个不使用指针的C/C++应用。用于存储数据和程序的地址,这是指针的基本功能。用于指向整型数,用整数指针(int*);指向浮点数用浮点数指针(float*);指向结构,用对应的结构指针(struct xxx *);指向任意地址,用无类型指针(void*)。 有时候,我们需要一些通用的指针。在C语言当中,(void*) 可以代表一切;但是在C++中,我们还有一些比较特殊的指针,无法用(void*)来表示。事实上,在C++中,想找到一个通用的指针,特别是通用...
C++中强制转换函数总结
标准c++中主要有四种强制转换类型运算符: const_cast,reinterpret_cast,static_cast,dynamic_cast等等。 1)static_castT*(a) 将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型。 表达式static_castT*(a), a的值转换为模板中指定的类型T.在运行时转换过程中,不进行类型检查来确保转换的安全性。 例子: class B { ... }; class D : public B { ... }; void f(B*...