http://groups.csail.mit.edu/graphics/classes/6.837/F04/index.html
Pointers
Arrays
String
Parameter Passing
Class Basics
Creating a Class
Constructors
- Called whenever a new instance is created
- Constructors can also take parameters, using this constructor with stack or heap allocation:
Destructors
- Called whenever an instance is deleted
Copy Constructors
Using a Class
Passing Classes as Parameters by reference is much faster
Creating an instance
Organizational Strategy
Class Hierarchy
- Child classes can call parent functions
- Child classes can override parent functions(same name,same parameters,is a virtual function)
- A superclass pointer can reference a subclass object
- If a superclass has virtual functions, the correct subclass version will automatically be selected(virtual function list)
- A pure virtual function has a prototype, but no definition【virtual void intersect(Ray *r, Hit *h) = 0;】.Used when a default implementation does not make sense.
- A class with a pure virtual function is called a pure virtual class and cannot be instantiated. (However, its subclasses can).
The main function
Coding Tips
- Use the #define compiler directive for constants
- Use the printf or cout functions for output and debugging
- Use the assert function to test “always true” conditions(如果表达式为FALSE, 程序将报告错误,并终止执行
- After you delete an object, also set its value to NULL (This is not done for you automatically)
- 【assert(myObject != NULL); myObject->setColor(RED);】debug memory allocation errors
- 注意数组越界、空指针、内存回收等问题
Advanced topics
friend友元
友元函数
- 能够访问类中的私有成员的非成员函数
- 友元关系不具对称性(即 A 是 B 的友元,但 B 不一定是 A 的友元。
- 友元关系不具传递性(即 B 是 A 的友元,C 是 B 的友元,但是 C 不一定是 A 的友元。
友元类
- 当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数。
- 友元关系不能被继承。
- 友元关系不具对称性(即 A 是 B 的友元,但 B 不一定是 A 的友元。
- 友元关系不具传递性(即 B 是 A 的友元,C 是 B 的友元,但是 C 不一定是 A 的友元。
public、protected、private
| 访问控制 | 访问权限 | |
| public |
基类的public和protected成员访问属性在派生类中保持不变, private成员不可直接访问。 |
派生类中的成员函数可以访问基类中的public和protected成员,不能直接访问基类的private成员。 派生类的对象只能访问public成员。 |
| protected |
基类的public和protected成员都以protected身份出现在派生类中, private成员不可直接访问。 |
派生类的成员函数可以直接访问基类中的public和protected成员,不能直接访问private成员。 派生类的对象不能直接访问从基类继承的任何成员。 |
| private |
基类的public和protected成员都以private身份出现在派生类中, private成员不可直接访问。 |
派生类的成员函数可以直接访问基类中的public和protected成员,不能直接访问private成员。 派生类的对象不能直接访问从基类继承的任何成员。 |
inline functions内联函数
- 消除调用函数时所造成的固有的时间消耗方法,因为不需要中断调用。
- 一般用于能够快速执行的函数,因为在这种情况下函数调用的时间消耗显得更为突出。
- 对于很小的函数也有空间上的益处,并且它也使得一些其他的优化成为可能。
- 在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来代替。
| inline | define |
|
参数的传递,参数是有数据类型的。 编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数) |
简单的字符串替换 |
|
函数调用是将实参的值传递给形参, 既然说是值,自然是计算得来的. |
宏的参数替换是不经计算而直接处理的 |
| 执行时调用 | 预编译 |
| 函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的。 | 宏的参数是不占内存空间的,因为只是做字符串的替换 |
|
函数的调用是需要付出一定的时空开销的, 因为系统在调用函数时,要保留现场,然后转入被调用函数去执行, 调用完,再返回主调函数,此时再恢复现场 |
|
|
内联函数可以访问类的成员变量, |
宏定义则不能; |
| 在类中声明同时定义的成员函数,自动转化为内联函数 |
static静态变量/函数
| 局部变量 | 只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回。 |
| 全局变量 | 全局变量只需在一个源文件中定义,就可以作用于所有的源文件。 |
| 静态局部变量 |
具有局部作用域。它只被初始化一次,自从第一次初始化直到程序结束都一直存在, 即 它的生命周期是程序运行就存在,程序结束就结束, 静态局部变量只对定义自己的函数体始终可见。 |
| 静态全局变量 |
具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里, 即 它的生命周期是程序运行就存在,程序结束就结束, 被static关键字修饰过的变量具有文件作用域。不可以和extern一起用。 可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。 |
| 类的静态成员变量 |
类静态数据成员在编译时创建并初始化:在该类的任何对象建立之前就存在,不属于任何对象 不属于某个对象,而是属于类的。 static修饰的成员变量需要在类外进行初始化。 sizeof 运算符计算对象所占用的存储空间时,不会将静态成员变量计算在内。 对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问; |
| 类的静态成员函数 |
不属于某个对象,而是属于类的。 静态成员函数也是属于类的成员,不能直接引用类的非静态成员,如果静态成员函数中要引用非静态成员时,可通过对象来引用。 静态成员函数属于整个类所有,没有this指针 static 成员变量实现了同类对象间信息共享。 static 成员类外存储,求类大小,并不包含在内。 static 成员只能类外初始化,但是可以在类内部声明。 |
- 全局变量、静态局部变量、静态全局变量都在静态存储区分配空间
- 局部变量在栈分配空间。
- static申明的变量定义时如果不初始化默认初始化为0
Const(为了取代define
- const修饰的变量为只读变量(不是常量,ANSI C还是要用define定义常量),定义一个const类型的变量时必须完成初始化 。
- 便于进行类型检查
- 节省空间,避免不必要的内存分配
const double Pi=3.14159; //此时并未将Pi放入ROM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配! - const也可以修饰函数的参数列表以及函数的返回值,参数返回值被const修饰代表参数和返回值均不能被改变。
- const修饰的变量可以通过强制类型转换转为非const(用const_cast)
- 被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
- const可以修饰函数的定义体,这里的函数为类的成员函数,承诺在本函数内部不会修改类内的数据成员,不会调用其它非 const 成员函数(也就是被const修饰函数定义体的函数)
compiler directives编译指令
- #include <xxx.h> 包含库函数
- #include "xxx.h" 包含本地头文件
- #define 标识宏名
- #undef 取消定义的宏
- #if、#elif、#else、#endif
- #ifdef、#ifndef、#endif
operator overloadins操作符重载
Vec3f& operator+(Vec3f &a, Vec3f &b);