geohash实现方式c++
2017-02-24 13:19:52 sundy_1995 阅读数 412
http://www.cnblogs.com/LBSer/p/3310455.html

http://www.sxrczx.com/pages/my.oschina.net/853294317/blog/296594.html

http://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=5300

受朋友委托写个查找附近人的算法,当然是不会写,不知道从何下手,于是学习了下geohash算法。看懂后开始一步步实现,当然还没有完全写完。不会之处在于:如何对已有的字符串进行前缀匹配的呢?怎么查找附近的人呢?

写了很多注释,怕自己以后看不懂。这也算是第一次体会到算法在工程中的作用。想起以前老师说算法在开发中没用!!表示汗颜、无语。

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string>
  4 #include<string.h>
  5 #include<map>
  6 #include <stdlib.h>
  7 #include <stdio.h>
  8 #include <winsock.h>
  9 #include <mysql.h>
 10 #include <cstring>
 11 using namespace std;
 12 map<string, string> base32;
 13 
 14 //将纬度、经度二进制化
 15 //纬度范围(-90, 90)
 16 //经度范围(-180, 180)
 17 //传入w,返回二进制编码
 18 //max_step控制递归次数同时也是二进制编码长度
 19 //注意返回的是逆序的字符串 max_step必须是5的倍数
 20 string geohash_w_bin(double w,double left,double right,int step,int max_step) 
 21 {
 22     if (step > max_step) 
 23     {
 24         return "";
 25     }
 26     double mid = (left + right)*1.0 / 2;
 27 
 28     if (w >= left && w <= mid) {
 29         return geohash_w_bin(w, left, mid,step+1,max_step)+"0"; 
 30     }
 31     if (w >= mid && w <= right) {
 32         return geohash_w_bin(w, mid, right,step+1,max_step)+"1";
 33     }
 34 
 35 }
 36 
 37 //合并经纬度
 38 //传入经度和纬度 返回合并的二进制编码
 39 string geohash_merge(string j, string w) {
 40     string s;
 41     for (int i = 0; i <j.size(); i++){
 42         s += j[i];
 43         s += w[i];
 44     }
 45     return s;
 46 }
 47 
 48 //二进制编码base32化
 49 string geohash_base32(string s) {
 50     string temp;
 51     string ans;
 52     for (int i = 0; i < s.size(); i++) {
 53         temp += s[i];
 54         if ((i + 1) % 5 == 0) {
 55             ans+=base32[temp];
 56             temp = "";
 57         }
 58     }
 59 
 60     return ans;
 61 }
 62 
 63 //*****************
 64 //将经纬度转为base32 返回base32编码
 65 //w为纬度 j为经度 
 66 //*****************
 67 string geohash(double j, double w) {
 68     string s_w="", s_j="";
 69     string s="", ss="";
 70     
 71     s_w = geohash_w_bin(w, -90, 90, 1, 30);
 72     s_j = geohash_w_bin(j, -180, 180, 1, 30);
 73     
 74     reverse(s_w.begin(), s_w.end());
 75     reverse(s_j.begin(), s_j.end());
 76 
 77     s = geohash_merge(s_j, s_w);
 78     s= geohash_base32(s);
 79     return s;
 80 }
 81 
 82 //有返回值的数据库写入
 83 MYSQL_RES * executeQuery(char *sql)
 84 {
 85     MYSQL* pConn = mysql_init(0);
 86     if (!mysql_real_connect(pConn, "localhost", "root", "root", "study1", 0, 0, 0))
 87     {
 88         goto error;
 89     }
 90     if (mysql_query(pConn, "set names gbk"))
 91     {
 92         goto error;
 93     }
 94     if (mysql_query(pConn, sql))
 95     {
 96         goto error;
 97     }
 98     
 99         MYSQL_RES *result = mysql_store_result(pConn);
100         mysql_close(pConn);
101         return result;
102     
103 error:
104         cout << "执行出错 " << mysql_error(pConn)<<endl;
105     //fprintf(cgiOut, "执行出错 %s", mysql_error(pConn));
106     //printf("执行出错 %s",mysql_error(pConn));
107 exit:
108     mysql_close(pConn);
109 }
110 
111 //无返回值的数据库写入
112 void executeNonQuery(char * sql)
113 {
114     MYSQL* pConn = mysql_init(0);
115     if (!mysql_real_connect(pConn, "localhost", "root", "root", "study1", 0, 0, 0))
116     {
117         goto error;
118     }
119     if (mysql_query(pConn, "set names gbk"))
120     {
121         goto error;
122     }
123     if (mysql_query(pConn, sql))
124     {
125         goto error;
126     }
127     goto exit;
128 error:
129     cout << "执行出错 " << mysql_error(pConn) << endl;
130     /*cgiHeaderContentType("text/html;charset=gbk");
131     fprintf(cgiOut, "执行出错 %s", mysql_error(pConn));*/
132     //printf("执行出错 %s",mysql_error(pConn));
133 exit:
134     mysql_close(pConn);
135 }
136 
137 
138 //字符串截取函数
139 string jiequ(string s, int l, int r) {
140     string temp;
141     for (int i = 0; i < r; i++)
142     {
143         temp += s[i];
144     }
145     return temp;
146 }
147 
148 
149 //输入base32编码,结果打印在屏幕上
150 //查询编码前缀相同的
151 void geohash_search(string base32)
152 {
153     for (int i = base32.size()-3; i > 0; i--)
154     {
155         string temp_base32 = jiequ(base32, 0, i);
156         const char *temp_c_base32 = temp_base32.c_str();
157         char sql[1024]; char *c = "%";
158         int f = 0;
159         
160         sprintf(sql, "select * from t_theatre where base32 like '%s%s'", temp_c_base32,c);
161         MYSQL_RES *result = executeQuery(sql);
162         MYSQL_ROW row;
163 
164         while (row = mysql_fetch_row(result))
165         {
166             char *base32 = row[1];
167             char *name = row[2];
168             cout << base32 << " " << name << endl;
169             //f = 1;
170         }
171 
172         /*if (f) {
173             return;
174         }*/
175 
176     }
177 
178 
179     
180 
181 }
182 int main()
183 {
184     base32["00000"] = "0";
185     base32["00001"] = "1";
186 
187     base32["00010"] = "2";
188     base32["00011"] = "3";
189 
190     base32["00100"] = "4";
191     base32["00101"] = "5";
192     base32["00110"] = "6";
193     base32["00111"] = "7";
194 
195     base32["01000"] = "8";
196     base32["01001"] = "9";
197     base32["01010"] = "b";//10
198     base32["01011"] = "c";//11
199     base32["01100"] = "d";//12
200     base32["01101"] = "e";//13
201     base32["01110"] = "f";//14
202     base32["01111"] = "g";//15
203 
204     base32["10000"] = "h";//16
205     base32["10001"] = "j";//17
206     base32["10010"] = "k";//18
207     base32["10011"] = "m";//19
208     base32["10100"] = "n";//20
209     base32["10101"] = "p";//21
210     base32["10110"] = "q";//22
211     base32["10111"] = "r";//23
212     base32["11000"] = "s";//24
213     base32["11001"] = "t";//25
214     base32["11010"] = "u";//26
215     base32["11011"] = "v";//27
216     base32["11100"] = "w";//28
217     base32["11101"] = "x";//29
218     base32["11110"] = "y";//30
219     base32["11111"] = "z";//31
220 
221     geohash_search("wttf1y0ewmt3");
222 
223     //select * from where like'wttc%'
224     //geohash_search("select * from t_theatre where base32 like 'wttc%'");
225     
226 
227     
228     /*while (1) {
229         double w, j; char name[128], sql[1024];
230         cin >> j >> w>>name;
231         
232         string base32=geohash(j,w);
233         const char *ch = base32.c_str();
234 
235         sprintf(sql, "insert into t_theatre(base32,name) values('%s','%s')", ch,name);
236         executeNonQuery(sql);
237     }*/
238 
239 
240     ////insert into t_theatre(base32) values()
241     //char sql[] = "insert into t_theatre(base32) values('klkl')";
242     //executeNonQuery(sql);
243     //120.677252 31.316891
244     //cout << geohash(120.677252, 31.316891) << " 精品酒店" << endl;
245     //cout << geohash(120.674144, 31.316012) << " 星海实验中学" << endl;
246     //    cout<< geohash(120.648933, 31.374867) << " 相称去政府" <<endl;
247     //cout << geohash(120.683958, 31.391834) << " 我的位置" <<endl;
248         
249     /*cout<<"111001001100011111101011100011000010110000010001010001000100";*/
250     ////double a = 90.0;
251     //string s=geohash_w_bin(104.031601, -180, 180, 1,30);
252     //reverse(s.begin(), s.end());
253     //cout << s<<endl;
254     ////cout << "101010111001001000100101101010";
255     ////cout << "110010011111101001100000000000";
256 
257     getchar();
258     return 0;
259 }
View Code

最后希望自己踏实学习算法。一张纸叠n次可以比天高,而n张纸叠在一起就不一定了。

2014-03-18 10:08:05 u011923747 阅读数 509
了解继承的概念之后,我们就来学习一下如何实现继承。

私有和保护

在第14章中我们说到,成员函数或成员数据可以是公有或者私有的。如果是公有的,那么它们可以被直接访问;如果是私有的,那么它们无法被直接访问。同时,我们还提到一个protected保留字,在没有使用继承的时候,它与private的效果是一样的,即无法被直接访问。如果使用了继承,我们就能体会到protected和private的差别。

private(私有)和protected(保护)都能实现类的封装性。private能够对外部和子类保密,即除了成员所在的类本身可以访问之外,别的都不能直接访问。protected能够对外部保密,但允许子类直接访问这些成员。public、private和protected对成员数据或成员函数的保护程度可以用下表来描述:

所以,当我们使用到继承的时候,必须考虑清楚:成员数据或成员函数到底应该是私有的还是保护的。

一个简单的例子

首先我们以一个学生类为例,介绍继承的写法:(程序17.3.1)
//student.h
#include <iostream>
using namespace std;
class student//学生类作为父类
{
   public:
   student(char *n,int a,int h,int w);//带参数的构造函数
   student();//不带参数的构造函数
   void set(char *n,int a,int h,int w);//设置
   char * sname();
   int sage();
   int sheight();
   int sweight();
   protected:
   char name[10];//姓名
   int age;//年龄
   int height;//身高
   int weight;//体重
   private:
   int test;
};
char * student::sname()
{
   return name;
}
int student::sage()
{
   return age; 
}
int student::sheight()
{
   return height;
}
int student::sweight()
{
   return weight;
}
void student::set(char *n,int a,int h,int w)
{
   int i;
   for (i=0;n[i]!='\0';i++)
   {
      name[i]=n[i];
   }
   name[i]='\0';
   age=a;
   height=h;
   weight=w;
   return;
}
student::student(char *n,int a,int h,int w)
{
   cout <<"Constructing a student with parameter..." <<endl;
   set(n,a,h,w);
}
student::student()
{
   cout <<"Constructing a student without parameter..." <<endl;
}
//undergraduate.h
#include "student.h"
class Undergraduate:public student//本科生类作为子类,继承了学生类
{
   public:
   double score();
   void setGPA(double g);//设置绩点
   bool isAdult();//判断是否成年
   protected:
   double GPA;//本科生绩点
};
double Undergraduate::score()
{
   return GPA;
}
void Undergraduate::setGPA(double g)
{
   GPA=g;
   return;
}
bool Undergraduate::isAdult()
{
   return age>=18?true:false;//子类访问父类的保护成员数据
}
//main.cpp
#include <iostream>
#include "undergraduate.h"
using namespace std;
int main()
{
   Undergraduate s1;//新建一个本科生对象
   s1.set("Tom",21,178,60);
   s1.setGPA(3.75);
   cout <<s1.sname() <<endl;
   cout <<s1.sage() <<endl;
   cout <<s1.sheight() <<endl;
   cout <<s1.sweight() <<endl;
   cout <<s1.score() <<endl;
   cout <<s1.isAdult() <<endl;
   return 0;
}

运行结果:
Constructing a student without parameter...
Tom
21
178
60
3.75
1
在使用继承之前,我们必须保证父类是已经定义好的。如果父类是虚无的、没有被定义的,那么子类也就没什么好继承的了。定义一个子类的语法格式为:
    class 子类名:继承方式父类名;
根据程序17.3.1的运行结果,我们可以清楚地看到,学生类里面的公有和保护成员都已经被继承到本科生类。本科生类可以使用学生类的成员函数,也可以访问学生类的保护成员。而本科生类中定义的成员则是对学生类的补充,并且也能够被使用。

继承的方式

在程序17.3.1中,我们选择的继承方式是public。和成员的类型一样,除了public之外,继承方式还有protected和private。那么,这三种继承方式到底有什么区别呢?

public是公有继承,或称为类型继承。它主要体现的是概念的延伸和扩展,父类所有的公有、保护成员都将按部就班地继承到子类中。父类的公有成员在子类中依然是公有的,父类的保护成员在子类中依然是保护的。比如程序17.3.1中的学生类和本科生类就是这样的关系。

private是私有继承,或称为私有的实现继承。它主要体现的是父类成员的重用。父类所有的公有、保护成员继承到子类时,类型会发生改变。父类的公有成员在子类中变成了私有成员,父类的保护成员在子类中也变成了私有成员。这时,我们可以利用从父类继承而来的成员函数来实现子类的成员函数,并且不必担心外部直接访问父类的成员函数,破坏了子类的秩序。比如我们认为栈是一种特殊的链表,它只能从链表尾部添加或删除结点,栈的压栈和退栈功能可以方便地由链表类的成员函数实现。但是,如果外部还能直接访问从链表类继承而来的成员函数,那么就可以在栈的任何位置插入结点,栈就会被破坏。

protected是保护继承,或称为保护的实现继承。与私有继承类似,它也是体现父类成员的重用。只不过父类的公有成员和保护成员在子类中都变成了保护成员。因此,如果有一个孙类继承了子类,那么父类中的成员也将被继承,成为孙类的保护成员。

public、private和protected三种继承方式可以用下表描述。其中右下角的九个单元格表示各种父类成员在对应的继承方式下,成为子类成员后的性质。
在使用继承的时候,我们必须根据实际需要选择合适的继承方式。下面我们以栈继承链表为例,理解一下私有继承方式:(程序17.3.2)
//node.h
#include <iostream>
using namespace std;
class Node
{
friend class Linklist;//链表类作为友元类
friend class Stack;//栈类作为友元类
public:
Node();
Node(Node &n);
Node(int i,char c='0');
Node(int i,char c,Node *p,Node *n);
~Node();
private:
int idata;
char cdata;
Node *prior;
Node *next;
};
Node::Node()
{
cout <<"Node constructor is running..." <<endl;
idata=0;
cdata='0';
prior=NULL;
next=NULL;
}
Node::Node(int i,char c)
{
cout <<"Node constructor is running..." <<endl;
idata=i;
cdata=c;
prior=NULL;
next=NULL;
}
Node::Node(int i,char c,Node *p,Node *n)
{
cout <<"Node constructor is running..." <<endl;
idata=i;
cdata=c;
prior=p;
next=n;
}
Node::Node(Node &n)
{
idata=n.idata;
cdata=n.cdata;
prior=n.prior;
next=n.next;
}
Node::~Node()
{
cout <<"Node destructor is running..." <<endl;
}
//linklist.h
#include "node.h"
#include <iostream>
using namespace std; 
class Linklist
{
public:
Linklist(int i=0,char c='0');
Linklist(Linklist &l);
~Linklist();
bool Locate(int i);
bool Locate(char c);
bool Insert(int i=0,char c='0');
bool Delete();
void Show();
void Destroy();
protected://原私有成员改为保护成员,以便于Stack类继承
Node head;
Node * pcurrent;
};
Linklist::Linklist(int i,char c):head(i,c)
{
cout<<"Linklist constructor is running..."<<endl;
pcurrent=&head;
}
Linklist::Linklist(Linklist &l):head(l.head)
{
cout<<"Linklist Deep cloner running..." <<endl;
pcurrent=&head;
Node * ptemp1=l.head.next;
while(ptemp1!=NULL)
{
Node * ptemp2=new Node(ptemp1->idata,ptemp1->cdata,pcurrent,NULL);
pcurrent->next=ptemp2;
pcurrent=pcurrent->next;
ptemp1=ptemp1->next;
}
}
Linklist::~Linklist()
{
cout<<"Linklist destructor is running..."<<endl;
Destroy();
}
bool Linklist::Locate(int i)
{
Node * ptemp=&head;
while(ptemp!=NULL)
{
if(ptemp->idata==i)
{
pcurrent=ptemp;
return true;
}
ptemp=ptemp->next;
}
return false;
}
bool Linklist::Locate(char c)
{
Node * ptemp=&head;
while(ptemp!=NULL)
{
if(ptemp->cdata==c)
{
pcurrent=ptemp;
return true;
}
ptemp=ptemp->next;
}
return false;
}
bool Linklist::Insert(int i,char c)
{
if(pcurrent!=NULL)
{
Node * temp=new Node(i,c,pcurrent,pcurrent->next);
if (pcurrent->next!=NULL)
{
pcurrent->next->prior=temp;
}
pcurrent->next=temp;
return true;
}
else
{
return false;
}
}
bool Linklist::Delete()
{
if(pcurrent!=NULL && pcurrent!=&head)
{
Node * temp=pcurrent;
if (temp->next!=NULL)
{
temp->next->prior=pcurrent->prior;
}
temp->prior->next=pcurrent->next;
pcurrent=temp->prior;
delete temp;
return true;
}
else
{
return false;
}
}
void Linklist::Show()
{
Node * ptemp=&head;
while (ptemp!=NULL)
{
cout <<ptemp->idata <<'\t' <<ptemp->cdata <<endl;
ptemp=ptemp->next;
}
}
void Linklist::Destroy()
{
Node * ptemp1=head.next;
while (ptemp1!=NULL)
{
Node * ptemp2=ptemp1->next;
delete ptemp1;
ptemp1=ptemp2;
}
head.next=NULL;
}
//stack.h
#include "linklist.h"
class Stack:private Linklist//私有继承链表类
{
public:
bool push(int i,char c);
bool pop(int &i,char &c);
void show();
};
bool Stack::push(int i,char c)
{
while (pcurrent->next!=NULL)
pcurrent=pcurrent->next;
return Insert(i,c);//用链表类的成员函数实现功能
}
bool Stack::pop(int &i,char &c)
{
while (pcurrent->next!=NULL)
pcurrent=pcurrent->next;
i=pcurrent->idata;
c=pcurrent->cdata;
return Delete();//用链表类的成员函数实现功能
}
void Stack::show()
{
Show();//用链表类的成员函数实现功能
}
//main.cpp
#include <iostream>
#include "stack.h"
int main()
{
Stack ss;
int i,j;
char c;
for (j=0;j<3;j++)
{
cout <<"请输入一个数字和一个字母:" <<endl;
cin >>i >>c;
if (ss.push(i,c))
{
cout <<"压栈成功!" <<endl;
}
}
ss.show();
while (ss.pop(i,c))
{
cout <<"退栈数据为i=" <<i <<" c=" <<c <<endl;
}
return 0;
}
运行结果:
Node constructor is running...
Linklist constructor is running...
请输入一个数字和一个字母:
1 a
Node constructor is running...
压栈成功!
请输入一个数字和一个字母:
2 b
Node constructor is running...
压栈成功!
请输入一个数字和一个字母:
3 c
Node constructor is running...
压栈成功!
0 0
1 a
2 b
3 c
Node destructor is running...
退栈数据为i=3 c=c
Node destructor is running...
退栈数据为i=2 c=b
Node destructor is running...
退栈数据为i=1 c=a
Linklist destructor is running...
Node destructor is running...

我们看到,Stack类私有继承了Linklist类之后,利用Linklist的成员函数,方便地实现了压栈和退栈功能。


原文:http://see.xidian.edu.cn/cpp/biancheng/view/91.html

2019-06-07 08:47:59 smartgps2008 阅读数 6

1。对象指针与函数指针:回调函数参数传入对象this和函数名称,否则只有全局函数或静态函数才能作为函数指针传递

2。std::function和std::bind

https://www.jianshu.com/p/f191e88dcc80

C++参考手册中对function的介绍:

std::function的实例能存储、复制及调用任何可调用的目标,包括:函数、lambda表达式、bind表达式或其他函数对象以及指向成员函数指针和指向数据成员指针,std::function包含在functional头文件中

std::function可以hold住任何可以通过“()”来调用的对象,包括:

  • 普通函数
  • 成员函数
  • 仿函数
  • lambda
  • std::bind

typedef  std::function<void(int, const char*)>  CallbackFunc;

void SubThread::setCallback(CallbackFunc  cb_func1);

void MainThread::executeFunc(int a, const char* s);

sub_thread.setCallback(std::bind(&MainThread::executeFunc, this, std::placeholders::_1, std::placeholders::_2));

 

2017-07-04 11:43:28 qq_29573053 阅读数 123

很多时候,我们需要提供一个类,这个类用来发出事件,通知程序中其他的组件进行处理,这可以通过回调来实现,下面是比较优雅的实现:

#include<boost/bind.hpp>
#include<boost/function.hpp>

using namespace boost;

class serialwraper
{
public:
    typedef boost::function<void(int)> CallBack;
    void RegisterCallBack(const CallBack& cb)
    {
        _cb=cb;
    }
    template<class C>
    void RegisterCallBack2(void (C::*fn)(int),C& c)
    {
        _cb=boost::bind(fn,const_cast<C&>(c),_1);

    }

    void dataHandle(int x)
    {
        if(_cb)
            _cb(x);
    }

private:
    CallBack _cb;

};
class serialHandler
{
public:
    int y;
    serialHandler():y(2)
    {

    }


public:
    void printData(int x)
    {
        std::cout<<x<<":"<<y<<std::endl;
    }
};

int main(int argc,char** argv)
{
    serialHandler sh;
    serialwraper sw;
    //sw.RegisterCallBack(boost::bind(&serialHandler::printData,sh,_1));
    sw.RegisterCallBack2(&serialHandler::printData,sh);
    sw.dataHandle(10);
    sh.y=3;
    sw.dataHandle(20);
   return 0;
}

上面的注册回调函数有两个写法
RegisterCallBack
RegisterCallBack2


核心的思路的boost::bind的使用,他可以将任何可调用对象(全局函数,成员函数,函数对象)重新构造成为一个函数对象,函数对象可以用boost::function来接收保存,供后续调用。

上述代码

boost::bind(&serialHandler::printData,sh,_1)
构造该可调用对象的时候,sh会值传递被拷贝到可调用对象内部,如果不想这样,可以使用ref(sh)。

2015-11-25 00:37:05 xufeng0991 阅读数 586
假设有一个简单类如下:
class Test{
private:
	int m;
public:
	Test(int i) {
		m = i;
	}
	int getM(){
		return m;
	}
	static void print() {
		cout << "static func" << endl;
	}
};

调用如下:
Test t(1);
a.getM();
Test::print();

C++类实现方式:
struct Test {
	int m;
};

// 构造函数
void Test_initialize(Test* this, int i) {
	this->m =i;
}

// 普通成员函数中默认传递了一个this指针
int Test_getM(Test* this) {
	return this->m;
}

// 静态成员函数中无this指针
void Test_print() {
	cout << "static func" << endl;
}

Test t;
Test_initialize(&t, 1);
Test_getM(&t);
Test_print();

C++多态的实现原理:
当类中声明虚函数时,编译器会在类中生成一个虚函数表
虚函数表是一个存储类成员函数指针的数据结构
虚函数表示由编译器自动生成和维护
virtul成员函数会被编译器放入虚函数表中
存在虚函数时,每个对象中都有一个只想虚函数表的指针(vptr)

class Parent {
public:
	virtual void func() {
	}
	virtual void func(int n) {
	}
};
VTABLE:
void Parent::func();
void Parent::func(int n);

Parent对象:
VPTR = &VTABLE;// 对象初始化完成之后才执行

class Child: public Parent {
public:
	virtual void func() {	
	}
	virtual void func(int n) {
	}
};
VTABLE:
void Child::func();
void Child::func(int n);

Child对象:
VPTR = &VTABLE;// 对象初始化完成之后才执行
 
调用如下:
void run(Parent* p) {
	p->func();
}

编译器确定func是否为虚函数:
是:根据对象的VPTR指针找到VTABLE,调用VTABLE中的func()函数(动态链接);
否:直接调用成员函数(静态编译)。

Child c;
c.VPTR指针分部初始化:
1 当执行父类的构造函数时,c.VPTR指向父类的虚函数表;
2 父类的构造函数执行完成后,c.VPTR只想子类的虚函数表;

C++单例模式实现方式

阅读数 607

//C++单例模式实现方式classCSingleton{private:///

博文 来自: dgyanyong

C和C++实现方式

阅读数 365

C++是一种具备面向对象能力的编程语言,所以,用C++来表达“我吃饭”这样一件事时,它的代码风格贴近这种人类的自然语言,即:我.吃(饭);“我”是一个对象,“吃”是“我”所属对象(人类)的一个函数,而“饭”是函数参数。 换成C语言,因为它不具备面向对象的设计思想,所以,它只能说成:“吃(我,饭)”。“吃”是函数,“我”和“饭”是两个参数。没有人规则一定要把“我”作为第一个参

博文 来自: ruanjianruanjianruan

字符串分割的c++实现方式

阅读数 883

char*p=strtok(str,seprator);while(p){CCLOG("%s\n",p);p=strtok(NULL,seprator);}

博文 来自: sonikk

C++继承的实现和方式

阅读数 246

了解继承的概念之后,我们就来学习一下如何实现继承。私有和保护在第14章中我们说到,成员函数或成员数据可以是公有或者私有的。如果是公有的,那么它们可以被直接访问;如果是私有的,那么它们无法被直接访问。同时,我们还提到一个protected保留字,在没有使用继承的时候,它与private的效果是一样的,即无法被直接访问。如果使用了继承,我们就能体会到protected和private的差别。

博文 来自: taylor_pool

C++ 多态性的实现方式

阅读数 1965

C++中多态性的实现方式   多态性是面向对象程序设计的一大支柱,它指的是在基类中定义的属性或服务被派生类继承之后,可以表现出不同的行为.也就是指一段程序能够处理不同类型对象的能力.在面向对象程序设计语言C++中,这种多态性的实现方式有4种,分别是强制多态、重载多态、类型参数化多态和包含多态.其中,类型参数化多态和包含多态称为一般多态性,用来系统地描述语义

博文 来自: edonlii
没有更多推荐了,返回首页