??xml version="1.0" encoding="utf-8" standalone="yes"?>
q种需求很?又因为C++和C是两U完全不同的~译链接处理方式,所以要E加处理.ȝ大致有两大类实现Ҏ(gu).
文中l出的是完整?具体?但又最基本最单的实现,至于理论性的东西在网上很Ҏ(gu)搜烦的到.
一.通过处理被调用的C头文?/strong>
a.h:
#ifndef __A_H
#define __A_H
#ifdef __cplusplus
extern "C" {
#endif
int ThisIsTest(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
a.c:
#include "a.h"
int ThisIsTest(int a, int b) {
return (a + b);
}
aa.h:
class AA {
public:
int bar(int a, int b);
};
aa.cpp:
#include "a.h"
#include "aa.h"
#include "stdio.h"
int AA::bar(int a, int b){
printf("result=%d\n", ThisIsTest(a, b));
return 0;
}
main.cpp:
#include "aa.h"
int main(int argc, char **argv){
int a = 1;
int b = 2;
AA* aa = new AA();
aa->bar(a, b);
delete(aa);
return(0);
}
Makefile:
all:
gcc -Wall -c a.c -o a.o
gcc -Wall -c aa.cpp -o aa.o
gcc -Wall -c main.cpp -o main.o
g++ -o test *.o
? 通过处理调用的C++文g
恢复a.h文gZ般性C头文?在aa.cpp文g中extern包含a.h头文件或函数.
a.h:
#ifndef __A_H
#define __A_H
int ThisIsTest(int a, int b);
#endif
aa.cpp:
extern "C"
{
#include "a.h"
}
#include "aa.h"
#include "stdio.h"
int AA::bar(int a, int b){
printf("result=%d\n", ThisIsTest(a, b));
return 0;
}
or
aa.cpp:
#include "aa.h"
#include "stdio.h"
extern "C"
{
int ThisIsTest(int a, int b);
}
int AA::bar(int a, int b){
printf("result=%d\n", ThisIsTest(a, b));
return 0;
}
typedef const char* ShapeType;
typedef IShape* (*Creator)();
Q-Q-Q-Q-Q-Q-ShapeFactory.hQ-Q-Q-Q-Q-Q-Q-Q-Q-Q-
class ShapeFactory {
public:
static ShapeFactory& Instance() {
static ShapeFactory instance;
return instance;
}
IShape* Create(ShapeType shapeType);
bool RegisterShape(ShapeType shapeType, Creator creator);
private:
ShapeFactory() {}
std::map<ShapeType, Creator> shapeCreators;
};
Q-Q-Q-Q-Q-Q-ShapeFactory.cppQ-Q-Q-Q-Q-Q-Q-Q-Q-Q-
#include "CFactory.h"
IShape* ShapeFactory::Create(ShapeType shapeType) {
Creator creator = shapeCreators.find( shapeType )->second;
if ( creator == NULL )
{
return NULL;
}
return creator();
}
bool ShapeFactory::RegisterShape( ShapeType shapeType, Creator creator ) {
map<ShapeType, Creator>::iterator iter;
iter = shapeCreators.find(shapeType);
if(iter != shapeCreators.end())
{
return false;
} else {
shapeCreators[shapeType] = creator;
return true;
}
}
Q-Q-Q-Q-Q-Q-CCircle .hQ-Q-Q-Q-Q-Q-Q-Q-Q-Q-
#include<stdio.h>
#include "IShape.h"
#include "CFactory.h"
class CCircle : public IShape
{
public:
CCircle()
{
printf("\n CCircle\n");
}
virtual ~CCircle()
{
printf("\n ~CCircle\n");
}
virtual void Draw();
};
Q-Q-Q-Q-Q-Q-CCircle .cppQ-Q-Q-Q-Q-Q-Q-Q-Q-Q-
#include "CCircle.h"
IShape* Create() { return new CCircle(); }
static const bool RegisterShape__ = ShapeFactory::Instance().RegisterShape( "CCircle", Create);
void CCircle::Draw()
{
printf("\n CCircle::Draw\n");
}
Q-Q-Q-Q-Q-Q-main.cppQ-Q-Q-Q-Q-Q-Q-Q-Q-Q-
#include<stdio.h>
#include"CFactory.h"
#include "IShape.h"
int main() {
IShape* line = ShapeFactory::Instance().Create("CCircle");
line->Draw();
return 0;
}
有点小的兴奋,大家U极发言哟!Q!
主要参考:(x) http://blog.csdn.net/jicao/archive/2006/07/01/861343.aspx
http://blog.csdn.net/hjsunj/archive/2008/01/07/2028597.aspx
《c++设计新思维?/p>
声明里面可以包括的元素有Q?/span>cd说明W?/span>(int, void, char,struct...)Q存储类?/span>extern, static, register, cd限定W?/span>(const, volatile), 变量?/span>(标识W?/span>), W号(*Q?/span>圆括号和中括?/span>)Q?/span>
M原则是,扑ֈ标识W?/span>(x?/span>们^时叫的变量名)Q从叛_左解析;
具体?/span>骤如下:(x)
1. 扑ֈ声明中最?/span>边的标识W?/span>,L标识W?/span> => 变量是叫“标识W?/span>”
2. 查看标识W右边的下一个符?/span>Q?/span>如果是方括号Q取出可能的大小Q去掉方括号 Q?/span>>是一个数l?/span>?/span>
3. 查看标识W右边的下一个符?/span>Q?/span>
如果是左圆括P取出可能的参敎ͼ一直到x?/span> Q?/span>> 是一个函?/span>
4. 查看标识W左边的W号Q?/span>如果是左括号Q找?/span>对应的右括号Qƈ把括号中的声明组合在一?/span>。回到第2步重新开始执行?/span>
5. 查看标识W左边的W号Q?/span>如果?/span>const, volatile,*, l箋向左ȝC是这三个cd为止?/span>重复W?span>4步? =>?/span>释ؓ(f)const, volatile,指向什么的指针
6. 剩下的符号一q?/span>d =>static unsigned int
你可能想问这几步可以解决了? 是的Q这是所谓的奇解码环?/span>
下面我来随便验证下这个算?span>:
先来个简单的
int (*a)[10] ?int* a[10];
声明?span> 步骤 执行l果
int (*a)[10] W?span>1?nbsp; 扑ֈ最左边的标识符aQ表C?span>a
是一?span>…int (*)[10] W?span>2Q?span>3?span> 不匹?/span>
int (*)[10] W?span>4?span> 匚w(,直接d),包括*Q表C?span>a是一个指?span>…指针.Step2
int [10] W?span>2?span> 匚w[10]Q表C?span>a是一个指?span>..size=10的数l的指针
int W?span>3Q?span>4Q?span>5 不匹?/span>
l束 W?span>6?span> 表示a是一个指?span>int数组的指?/span>
int* a[10] W?span>1?span> a是一?/span>
int* [10] W?span>2?span> a是一?span>…size=10的数l?/span>
int* W?span>3?span> 不匹?/span>
int W?span>4?span> 匚wQ?span>a是一个存攄指针Q?span>size=10的数l?/span>
int W?span>5?span> 匚wQ?span>a是一个存攄int指针Q?span>size=10的数l?/span>
大家?/span>的出两个声明的结果是一个是指针Q一个是数组?/span>
int a1[10];
int a2[20];
int (*b)[10];
int* c[10];
a[0] = 10;
b = &a2; //报错Q?/span>cannot convert from 'int (*)[20]' to 'int (*)[10]'
b = &a1; //b是指?/span>size=10的数l的指针
c[0] = &a1[0]; //c是一个数l,里面存放的是指针Q指针指?/span>int;
我的E序很简单,是把之前通过一个结构体fwrite到文?/span>A里的内容dQ然后{l另一个结构体保存。程序是单,但我担心的是之前?/strong>l构?/span>fwrite到文?/span>A的程序对齐结构体规则是怎样的?一定要知道它吗? 当然了,如果那个E序l构体是按照1寚w写入的,我的E序l构体是按照4寚wdQ那不就p了Q?/span>
q里我引入结构体寚w的概念,也可以说是内存对齐了。ؓ(f)什么要内存寚w呢,是方便CPUd了,具体原因大家要参考计机体系l构了。先看一个内存对齐的例子Q?/span>
struct example1{
char a;
double b;
long l;
};
struct example2{
char a;
long l;
double b;
};
大家算l构体大,初次接触的博友可能对{案有点惊讶Q?/span>VC~译Q?/span> sizeof后结果分别是Q?/span>24Q?/span>16?/span> 同样是的l构体,成员换了序Q大就不同了。其实内存对齐有个规则,只要知道了,?/span>OK。那么以?/span>5Ҏ(gu)关键
1Q?span>
内存寚w与编译器讄有关Q首先要搞清~译器这个默认值是多少2Q?span> 如果不想~译器默认的话,可以通过#pragma pack(n)来指定按?/span>n寚w
3Q?span> 每个l构体变量对齐,如果寚w参数n(~译器默认或者通过pragma指定)大于该变量所占字节数(m)Q那么就按照m寚wQ内存偏Ud的地址?/span>m的倍数Q否则是按照n寚wQ内存偏Ud的地址?/span>n的倍数。也是最化长度规则
4Q?span> l构体d?/span>: 寚w后的长度必须是成员中最大的寚w参数的整数倍。最大对齐参数是从第三步得到的?/span>
5Q?span> 补充Q如果结构体A中还要结构体BQ那?/span>B的对齐方式是选它里面最长的成员的对齐方?/span>
所以计结构体大小要走三步Q首先确定是当前E序按照几对?/span>(参照1Q?/span>2?/span>)Q接着计算每个l构体变量的大小和偏U?/span>(参照3Q?/span>5)Q最后计结构体d(参照4Q?/span>
先算?/span>example1吧,假设~译器是?/span>16寚w?/span>
1Q确定按照几寚w: 16;
2Q确定每个成员的偏移Q?/span>a 占一个字节,16>1, 按照1寚wQv始位|?/span>0Q?/span>0%1 = 0Q那?/span>a存?/span>0位置Q?/span>b?/span>8个字节,16>8Q按?/span>8寚wQv始位|就不能?/span>1了,因ؓ(f)要按?/span>8寚wQ所以最q的偏移起始位置?/span>8Q?/span> 8%8 =0, 那么b存在位|?/span>8-15的位|;l?/span>4个字节,16>4Q按?/span>4寚wQv始位|?/span>16Q?/span> 16%4=0Q那?/span>l存在位|?/span>16-19的位|。所以结构体?/span>0?/span>19一共占?/span>20个字?/span>
3Q结构体d:(x)成员中最大的寚w参数?/span>b?/span>8寚wQ所?/span>20Q?/span>8!=0, 24刚好?/span>
真的很搞Q同理计?/span>example2应该?/span>16Q?/span>
再D个结构体嵌套的例子吧Q?/span>
#pragma pack(push)
#pragma pack(8)
struct test1{
int a;
char b;
int c[20]
long l;
} ;
struct test2{
char a1;
char a2;
struct test1 t1;
double b1;
}
#pragma pack(pop)
先计?/span>test1, 8寚wQ?/span>a占用0-3Q?/span>b占用4Q?/span>c占用8Q?/span>87Q?/span>l占用88Q?/span>91Q一?/span>92个字节。成员中最大的寚w参数?/span>int?/span>92%4=0;
再计?/span>test2, a1z占用0Q?/span>a2占用1Q?/span>t1呢,4 % 4 (test1里面最长的成员的对齐方? = 0, 4-95Q?/span>b1?/span>96?/span>103Q一?/span>104个字节,成员中最大的寚w参数?/span>double?/span>104%8=0; 所以是104.
那关于我文章开头提到的那个文g转换Q我现在只要知道原始E序是按照什么对齐的Q然后在新程序中指定按照几对齐就可以了,哈哈Q?nbsp;
挤时间写的,有的地方有遗漏,请各位指正!
void fn3() {printf("\n ClassA: fn3()\n");}
void fn4(int i){printf("\n ClassA: fn4()\n");}
};
int main()
{
Base* pBase1 = new ClassA(10, 20);
pBase1->fn(); //OKQClassA: fn()
pBase1->fn(11); //OKQClassA: fn(INT)
pBase1->fn2(); //OKQBase: void fn2(int)
pBase1->fn2(2); //NO, 不能讉K
pBase1->fn3(); //OKQBase: fn3()
pBase1->fn4(); //OKQBase: fn4()
pBase1->fn4(2); //NOQ不能访?br> printf("\n============================================\n");
ClassA* pDerived = new ClassA(10, 20);
pDerived->fn(); //OKQClassA: fn()
pDerived->fn(1); //OKQClassA: fn(INT)
pDerived->fn2(); //NOQ不能访?br> pDerived->fn2(2); //OKQClassA: fn2(INT)
pDerived->fn3(); //OKQClassA: fn3()
pDerived->fn4(); //NOQ不能访?br> pDerived->fn4(2); //NOQClassA: fn4(INT)
printf("\n============================================\n");
return 0;
}
子类父类同名virtual函数(参数相同)Q?用子cȝ指针Q引用,对象讉KӞ子类?x)覆盖父cL?只能讉K子类Ҏ(gu))?br>子类父类同名virtual函数(参数相同)Q?用父cȝ指针Q引用,对象讉KӞ子类?x)覆盖父cL?只能讉K子类Ҏ(gu))?br>子类父类同名virtual函数(参数不同)Q?用子cȝ指针Q引用,对象讉KӞ子类?x)覆盖父cL?只能讉K子类Ҏ(gu))?br>子类父类同名virtual函数(参数不同)Q?用父cȝ指针Q引用,对象讉KӞ父类?x)覆盖子cL?只能讉K父类Ҏ(gu))?br>子类父类同名virtual函数(函数cd不同const/non-const)Q?用子cȝ指针Q引用,对象讉KӞ子类?x)覆盖父cL?只能讉K子类Ҏ(gu))?br>子类父类同名virtual函数(函数cd不同const/non-const)Q?用父cȝ指针Q引用,对象讉KӞ父类?x)覆盖子cL?只能讉K父类Ҏ(gu))?/p>
l论Q参数和函数cd是c++~译器判断要不要多态的关键因素。注: q回cd不同Ӟ~译器会(x)报错Qvirtual不能和staticq用。静态成员函敎ͼ没有隐藏的this指针Qvirtual函数一定要通过对象来调用,既要this指针?br>改进:Q如果子cL针想讉K到父c,可以在子c里加入:using 父类?:函数名;如pDerived->fn2(); 讉K父类Ҏ(gu)Q在ClassA里面加入using Base::fn2Q就可以讉K了。如果父cL针想讉K到子c,需要指针{换了?br>
子类父类同名non-virtual函数(无论参数/q回/函数cd(const或static))Q用子类的指针,引用Q对象访问,子类?x)覆盖父cL?只能讉K子类Ҏ(gu))?br>子类父类同名non-virtual函数(无论参数/q回/函数cd(const或static))Q用父类的指针,引用Q对象访问,父类?x)覆盖子cL?只能讉K父类Ҏ(gu))?br>
l论: non-virtual函数Q既没有M多态效果,如果父类要访问子c,只用指针转换?nbsp;
所谓大道至Q想必大家看着q个都烦Q我也是。想了想应该q样表达最单:(x)
子类publicl承父类的函敎ͼ唯有满(参数Q返回|函数cd相同&父类是virtual)函数Q父cȝ指针Q引?也指针实现的)能够多态的讉K子类Q否则父cL针只能访问父cȝҎ(gu)?nbsp;
子类publicl承父类的函敎ͼ子类的方法名?x)遮掩父cȝ相同名的Ҏ(gu)。子c要惌问父cȝҎ(gu)Q用using 父类?:函数名?nbsp;
具体的原因我觉得可能q是得找旉拜读下候杰译的《C++对象模型》,看看到底q个东西是怎么设计的?br>
举个例子Q交通工L(fng)可以z出汽车和船两个子c,但拥有汽车和船共同特性水陆两用汽车就必须l承来自汽RcM船类的共同属性?
由此我们不难惛_如下的图例与代码Q?/p>
当一个派生类要用多重承的时候,必须在派生类名和冒号之后列出所有基cȝcdQƈ用逗好分隔?/font>
#include <iostream>
using namespace std;
class Vehicle
{
public:
Vehicle(int weight = 0)
{
Vehicle::weight = weight;
}
void SetWeight(int weight)
{
cout<<"重新讄重量"<<endl;
Vehicle::weight = weight;
}
virtual void ShowMe() = 0;
protected:
int weight;
};
class Car:public Vehicle//汽R
{
public:
Car(int weight=0,int aird=0):Vehicle(weight)
{
Car::aird = aird;
}
void ShowMe()
{
cout<<"我是汽RQ?<<endl;
}
protected:
int aird;
};
class Boat:public Vehicle//?nbsp;
{
public:
Boat(int weight=0,float tonnage=0):Vehicle(weight)
{
Boat::tonnage = tonnage;
}
void ShowMe()
{
cout<<"我是船!"<<endl;
}
protected:
float tonnage;
};
class AmphibianCar:public Car,public Boat//水陆两用汽R,多重l承的体?nbsp;
{
public:
AmphibianCar(int weight,int aird,float tonnage)
:Vehicle(weight),Car(weight,aird),Boat(weight,tonnage)
//多重l承要注意调用基cL造函?nbsp;
{
}
void ShowMe()
{
cout<<"我是水陆两用汽RQ?<<endl;
}
};
int main()
{
AmphibianCar a(4,200,1.35f);//错误
a.SetWeight(3);//错误
system("pause");
}
上面的代码从表面看,看不出有明显的语发错误,但是它是不能够通过~译的。这有是Z么呢Q?
q是׃多重l承带来?font color=#ff0000>l承的模p?/font>带来的问题?/p>
先看如下的图C:(x)
在图中深U色标记出来的地Ҏ(gu)是主要问题所在,水陆两用汽Rcȝ承了来自CarcMBoatcȝ属性与Ҏ(gu)QCarcMBoatcd为AmphibianCarcȝ基类Q在内存分配上AmphibianCar获得了来自两个类的SetWeight()成员函数Q当我们调用a.SetWeight(3)的时候计机不知道如何选择分别属于两个基类的被重复拥有了的cL员函数SetWeight()?
׃q种模糊问题的存在同样也D了AmphibianCar a(4,200,1.35f);执行p|Q系l会(x)产生Vehicle”不是基或成员的错误?/p>
以上面的代码ZQ我们要惌AmphibianCarcL获得一个Vehicle的拷贝,而且又同时共享用CarcMBoatcȝ数据成员与成员函数就必须通过C++所提供?font color=#ff0000>虚拟l承技术来实现?/p>
我们在CarcdBoatcȝ承VehiclecdQ在前面加上virtual关键字就可以实现虚拟l承Q用虚拟承后Q?font style="BACKGROUND-COLOR: #b000b0" color=#ffffff>当系l碰到多重承的时候就?x)自动先加入一个Vehicle的拷贝,当再ơ请求一个Vehicle的拷贝的时候就?x)被忽略Q保证承类成员函数的唯一?/font>?
修改后的代码如下Q注意观察变化:(x)
#include <iostream>
using namespace std;
class Vehicle
{
public:
Vehicle(int weight = 0)
{
Vehicle::weight = weight;
cout<<"载入VehiclecL造函?<<endl;
}
void SetWeight(int weight)
{
cout<<"重新讄重量"<<endl;
Vehicle::weight = weight;
}
virtual void ShowMe() = 0;
protected:
int weight;
};
class Car:virtual public Vehicle//汽RQ这里是虚拟l承
{
public:
Car(int weight=0,int aird=0):Vehicle(weight)
{
Car::aird = aird;
cout<<"载入CarcL造函?<<endl;
}
void ShowMe()
{
cout<<"我是汽RQ?<<endl;
}
protected:
int aird;
};
class Boat:virtual public Vehicle//?q里是虚拟?nbsp;
{
public:
Boat(int weight=0,float tonnage=0):Vehicle(weight)
{
Boat::tonnage = tonnage;
cout<<"载入BoatcL造函?<<endl;
}
void ShowMe()
{
cout<<"我是船!"<<endl;
}
protected:
float tonnage;
};
class AmphibianCar:public Car,public Boat//水陆两用汽R,多重l承的体?nbsp;
{
public:
AmphibianCar(int weight,int aird,float tonnage)
:Vehicle(weight),Car(weight,aird),Boat(weight,tonnage)
//多重l承要注意调用基cL造函?nbsp;
{
cout<<"载入AmphibianCarcL造函?<<endl;
}
void ShowMe()
{
cout<<"我是水陆两用汽RQ?<<endl;
}
void ShowMembers()
{
cout<<"重量Q?<<weight<<","<<"I气排量Q?<<aird<<"CCQ?<<"排水量:(x)"<<tonnage<<"?<<endl;
}
};
int main()
{
AmphibianCar a(4,200,1.35f);
a.ShowMe();
a.ShowMembers();
a.SetWeight(3);
a.ShowMembers();
system("pause");
}
注意观察cL造函数的构造顺序?
虽然说虚拟承与虚函数有一定相似的地方Q但读者务必要CQ他们之间是l对没有M联系的!
AOP技术在Javaq_下是最先得到应用的。就在PARC对于面向斚w~程q行研究的同Ӟ国Northeastern University的博士生Cristina Lopes和其同事也开始了cM的思考。最l,国国防先进技术研I计划vQDefense Advanced Research Projects Agency即DARPAQ注意到了这工作,q提供了U研l费Q鼓励将二者的工作成果l合h。他们通过定义一套Java语言的扩展系l,使开发者可以方便的q行面向斚w的开发,q套扩展pȝ被称为AspectJ。之后,AspectJ?002q被转让lEclipse FoundationQ从而成为在开源社ZAOP技术的先锋Q也是目前最为流行的AOP工具?br>
那么对于C++技术来_(d)怎样来开展AOP呢,q好有Olaf Spinczyk q样的h存在Q我们也有了aspect c++。它使用了插入代码的Ҏ(gu)。一个典型的Aspect C++CZ需要一个C++源文?.cpp)、一个aspect C++源文?.ah)Q通过ac++~译器把C++源文件和aspect C++源文件{换成混合的C++源文?如果有头文g也会(x)转换)Q最后通过普通的C++~译器编译出可执行文件?br>
那么我现在如果不想用W三方编译器Q自己去实现AOPQ不知道CPPBLOG里的大虾有什么想法?
我在?/span>C/C++函数Ӟ从没有全面考虑q该函数功能Q只是知道它能做Q基本对函数l节没有了解Q就拿下面这个函数做个例子:(x)
char *inet_ntoa(struct in_addr in);
struct in_addr { unsigned long int s_addr; }
看到q个我就能想到该函数是把一?/span>unsigned long type的数转换成一个字W串。其它什么都不想。现在让我们来仔l品读里面的东西?/span>
我传入一?/span>unsigned long type的数据,它给我传Z?/span>char *Q那q个char * 在函数里怎么分配I间的。首先不可能是堆分配Q因为如果是那样的话Q你用完q个函数后还要释放资源。其ơ不可能是栈分配Q因为那样函数返回后栈也?x)跟着释放。那q有可能是全局变量Q如果这L(fng)话,C/C++中已l有好多全局了。那q有一U是static的可能,static不会(x)随着函数的返回而释放,也就是说Q它是一块长期被分配的内存空_(d)现在在假若我在程序中q样写:(x)
printf(“%s, %s”, inet_ntoa(a), inet_ntoa(b)); //a, b 是两个不相等的?/span>
输出?x)让我大吃一惊,输出l果一栗原因很单,是printf先求bQ把值给了那?/span>staticQ然后再?/span>a, 把值又l了staticQ?/span>static的那块内存最l被写入?/span>a的|q个时候输出,那当然就输出的同一个g。还有一U错误写法,如下Q?/span>
Char *tmp1 = inet_ntoa(a);
Char *tmp2 = inet_ntoa(b);
q样也是有问题的Q因?/span>tmp1?/span>tmp2都指向了一块内存,当前?/span>static的值就?/span>b的g。所以ȝ如下Q用这U函C定要copy函数q回的|而不能去保存其内存地址Q?br>附inet_ntoa()源码Q?br>#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <bits/libc-lock.h>
/* The interface of this function is completely stupid, it requires a
static buffer. We relax this a bit in that we allow at least one
buffer for each thread. */
/* This is the key for the thread specific memory. */
static __libc_key_t key;
/* If nonzero the key allocation failed and we should better use a
static buffer than fail. */
static char local_buf[18];
static char *static_buf; //静?/span>
/* Destructor for the thread-specific data. */
static void init (void);
static void free_key_mem (void *mem);
char *
inet_ntoa (struct in_addr in)
{
__libc_once_define (static, once);
char *buffer;
unsigned char *bytes;
/* If we have not yet initialized the buffer do it now. */
__libc_once (once, init);
if (static_buf != NULL)
buffer = static_buf;
else
{
/* We don't use the static buffer and so we have a key. Use it
to get the thread-specific buffer. */
buffer = __libc_getspecific (key);
if (buffer == NULL)
{
/* No buffer allocated so far. */
buffer = malloc (18);
if (buffer == NULL)
/* No more memory available. We use the static buffer. */
buffer = local_buf;
else
__libc_setspecific (key, buffer);
}
}
bytes = (unsigned char *) ∈
__snprintf (buffer, 18, "%d.%d.%d.%d",
bytes[0], bytes[1], bytes[2], bytes[3]);
return buffer;
}
/* Initialize buffer. */
static void
init (void)
{
if (__libc_key_create (&key, free_key_mem))
/* Creating the key failed. This means something really went
wrong. In any case use a static buffer which is better than
nothing. */
static_buf = local_buf;
}
C Q?/span>
struct Node{ // 声明
int node;
struct Node *next; // 定义
};
struct Node list;
或?/span>
typedef Node {
int node;
struct Node *next;
}ListLink;
ListLink list;
C++:
struct Node{
Int node;
Node *next;
};
Node list; // 搞定?/span>
q样一?/span> C++ 的确实在代码的层面上单了Q但理解h却不是很舒服Q?/span>
今天刚接CQ务做 Wireless-Lan Q好长时间没做正事了Q这两天主要在写文档Q东西还比较多,但是和我一l的 Danel人很?/span> Q给我讲了下整个 class diagram 的流E,虽没?/span> sequence 那么Ҏ(gu)理解Q但我还是懂了。而且我发C写程序时特别开心,心态很好,q也是我在追求的Q慢慢来吧。ȝ说这周五之前做出点东西,呵呵Q不能让他失望呀Q过?x)再看看代码Q?/span> GUI Q我蛮喜Ƣ写的?/span>
再说说今天用的那个工P SOURCE INSIGHT Q真爽。看代码的强有力工具。下ơ给 PASSION 的兄弟们介绍下?/span>
执行Q?/p>