001 Figuring in C/C++
1. forward declaration
// Function void fun(int);在此之后的代码可以引用fun,而fun的定义必须在某个地方提供。
// Variables may have only forward declaration and lack definition // During compilation time these are initialized by language specific rules int foo; //foo might be defined somewhere in this file extern int bar; //bar must be defined in some other file在其他文件中定义的变量必须用extern进行前置声明。
// Type class A; struct B; A fun(A arg); // Pass A* pa; // Pass, but can't (*pa).member or pa->somefun(); A& ra = *pa; // Pass, but cant't ra; ra.member; ra.somefun(); A a; // Error在知道这个类型的完整定义之前,只能用于作为类型的声明,而不能实际的定义变量。
2. POD type 包括以下类型
scalar types |
arithmetic types |
integral types - [unsigned]char,short,int,long,bool,wchar_t; |
floating types - float,double,long double; |
||
enumeration types | enumerations | |
pointer types | pointer to void(void*); pointer to object/static member data(T*); pointer to function/static member function(T(*)(...)); |
|
point-to-member types | pointer to non-static member data (T C::*); pointer to non-static member function (T (C::*)(...)); |
|
POD class types | Aggregate POD struct types and Aggregate POD union types |
None of following as member: non-static data(including arrays)of any point-to-member type; non-static data(including arrays)of any non-POD class type; non-static data of any reference type; user-define of copy assignment operator; user-define destructor; Aggreagate refers None of following characteristics: user-declared constructor; private or protected non-static data members; base classes; virtual functions; |
扩展:http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html
3. 初始化列表的意义
列表先于构造函数调用,并调用父类,成员的构造函数进行初始化。(若在列表初始化成员,则无需在{}中再次的赋值初始化,有一定的效能提升)
初始化列表顺序:父类,成员声明的顺序。
4. Return Value Optimization
struct L { int la; L() { printf("Default Ctor L %p:%d\n", this, la); } L(int a):la(a) { printf("User Ctor L %p:%d\n", this, la); } L(const L& ot) { if( this != (&ot)){(*this) = ot;}; printf("Copy L %p from %p %d\n", this, &ot, la); } L& operator=(const L&ot) { la=ot.la; printf("=L %p from %p %d\n", this, &ot, la); return (*this); } ~L() { printf("~L %p:%d\n", this, la); } }; L fun(L arg) { printf("funin\n"); return L(arg); // or // L tl = arg; // return tl; } int main() { fun(1); printf("funout\n"); return 0; } // one possible output in gcc 3.4.4 /* User Ctor L 0xbff89990:1 // 参数构造 funin =L 0xbff899a0 from 0xbff89990 1 Copy L 0xbff899a0 from 0xbff89990 1 // 函数内局部对象拷贝构造 ~L 0xbff899a0:1 // 函数内局部对象析构 ~L 0xbff89990:1 // 参数析构 funout */按照道理,这里应该有三个对象的析构才对:函数内局部对象,返回于函数调用栈的临时对象,函数的参数。
再来看下面的输出
L object = fun(1); printf("funout\n"); return 0; // one possible output in gcc 3.4.4 /* User Ctor L 0xbfe0b3d0:1 // 参数构造 funin =L 0xbfe0b3e0 from 0xbfe0b3d0 1 Copy L 0xbfe0b3e0 from 0xbfe0b3d0 1 // 函数内局部对象拷贝构造 ~L 0xbfe0b3d0:1 // 参数析构 funout ~L 0xbfe0b3e0:1 // object析构 */
按照道理,这里应该有四个对象的析构才对:函数内局部对象,返回于函数调用栈的临时对象,函数的参数,对象object。
RVO是一项编译器相关的代码优化技术,在这里我们可以发现在对object进行拷贝构造时也优化了。
版权声明:本文为博主原创文章,未经博主允许不得转载。