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

```  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;
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

2014-03-18 10:08:05 u011923747 阅读数 509

## 私有和保护

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

## 一个简单的例子

//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;
}
#include "student.h"
{
public:
double score();
void setGPA(double g);//设置绩点
protected:
double GPA;//本科生绩点
};
{
return GPA;
}
{
GPA=g;
return;
}
{
return age>=18?true:false;//子类访问父类的保护成员数据
}
//main.cpp
#include <iostream>
using namespace std;
int main()
{
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;
return 0;
}

Constructing a student without parameter...
Tom
21
178
60
3.75
1

class 子类名：继承方式父类名；

## 继承的方式

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

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

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

public、private和protected三种继承方式可以用下表描述。其中右下角的九个单元格表示各种父类成员在对应的继承方式下，成为子类成员后的性质。

//node.h
#include <iostream>
using namespace std;
class Node
{
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;
}
#include "node.h"
#include <iostream>
using namespace std;
{
public:
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 * pcurrent;
};
{
}
{
while(ptemp1!=NULL)
{
Node * ptemp2=new Node(ptemp1->idata,ptemp1->cdata,pcurrent,NULL);
pcurrent->next=ptemp2;
pcurrent=pcurrent->next;
ptemp1=ptemp1->next;
}
}
{
Destroy();
}
{
while(ptemp!=NULL)
{
if(ptemp->idata==i)
{
pcurrent=ptemp;
return true;
}
ptemp=ptemp->next;
}
return false;
}
{
while(ptemp!=NULL)
{
if(ptemp->cdata==c)
{
pcurrent=ptemp;
return true;
}
ptemp=ptemp->next;
}
return false;
}
{
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;
}
}
{
{
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;
}
}
{
while (ptemp!=NULL)
{
cout <<ptemp->idata <<'\t' <<ptemp->cdata <<endl;
ptemp=ptemp->next;
}
}
{
while (ptemp1!=NULL)
{
Node * ptemp2=ptemp1->next;
delete ptemp1;
ptemp1=ptemp2;
}
}
//stack.h
{
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...

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...

Node destructor is running...

Node destructor is running...

Node destructor is running...

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 MainThread::executeFunc(int a, const char* s);

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(&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成员函数会被编译器放入虚函数表中

```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();
}```

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

C++单例模式实现方式

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

C和C++实现方式

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

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

C++继承的实现和方式

C++ 多态性的实现方式

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