返回数组的形式
直接return array只会返回第一个元素哦!下面介绍四种返回数组方法
#include <iostream>#include <string.h>#include <math.h>#define CITY_NUM 11000class LbsIndexCity{public: LbsIndexCity(int city_id):m_city_id(city_id){} int get_city_id(){ return m_city_id; }private: int m_city_id;};LbsIndexCity* m_city[CITY_NUM];void add_m_city(int city_id){ m_city[101]=new LbsIndexCity(city_id);}/*1.LbsIndexCity* (* get_m_city())[CITY_NUM]{ return &m_city;}*//*2.typedef LbsIndexCity* arrT[CITY_NUM];arrT * get_m_city(){ return &m_city;}*//*3.auto get_m_city() -> LbsIndexCity*(*)[CITY_NUM]{ return &m_city;}*/LbsIndexCity* arrT[CITY_NUM]={nullptr};decltype(arrT) *get_m_city(){ return &m_city;}int main() { add_m_city(1001); LbsIndexCity* (*m_city)[CITY_NUM] = get_m_city(); for(int city_id =0; city_id < CITY_NUM; city_id++) { if((*m_city)[city_id] == NULL){ continue ; }else{ std::cout <<(*m_city)[city_id]->get_city_id()<<std::endl; } } std::cout << "cyy,Hello, World!" <<std::endl; return 0;}
单例
1.饿汉实现
/*饿汉实现 * 由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间 * 显示调用Destroy * */template <class T>class singleton{private: static T* p; singleton(){} ~singleton(){}public: static T* GetInstance(); static void Destroy(); //需要在退出时显示调用};template <class T>T* singleton<T>::p = new T();template <class T>T* singleton<T>::GetInstance(){ return p;}template <class T>void singleton<T>::Destroy(){ if(p == nullptr){ return ; } std::cout<<"delete~"<<std::endl; delete p;}
2.懒汉实现 pthread_once,atexit(Destroy);
#include "pthread.h"#include <stdlib.h>#include <iostream>/*懒汉实现 * 在访问量较小时,采用懒汉实现,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化 * 显示调用析构 * */template <class T>class singleton2{protected: singleton2(){};private: singleton2(const singleton2&){}; singleton2& operator=(const singleton2&){}; static T* m_instance; static pthread_once_t m_once; //static pthread_mutex_t g_mutex;public: static void Init(); static void Destroy(); static T* GetInstance();};template <class T>void singleton2<T>::Destroy(){ if(m_instance == nullptr){ return ; } delete m_instance;}template <class T>void singleton2<T>::Init(){ m_instance = new T(); atexit(Destroy);}template <class T>T* singleton2<T>::GetInstance(){ pthread_once(&m_once,Init); return m_instance;}template <class T>pthread_once_t singleton2<T>::m_once = PTHREAD_ONCE_INIT;template <class T>T* singleton2<T>::m_instance = NULL;
2.懒汉实现 锁,atexit(Destroy);
template <class T>class singleton2{protected: singleton2(){};private: singleton2(const singleton2&){}; singleton2& operator=(const singleton2&){}; static T* m_instance; static pthread_once_t m_once; //static pthread_mutex_t g_mutex;public: static void Init(); static void Destroy(); static T* GetInstance();};template <class T>void singleton2<T>::Destroy(){ if(m_instance == nullptr){ return ; } delete m_instance;}template <class T>T* singleton2<T>::m_instance = NULL;template <class T>pthread_mutex_t singleton2<T> ::g_mutex = PTHREAD_MUTEX_INITIALIZER;template <class T>T* singleton2<T>::GetInstance(){ if( m_instance == NULL) { pthread_mutex_lock(&g_mutex); if( m_instance == NULL) { T* ptmp = new T(); m_instance = ptmp; //防止多线程顺序 atexit(Destroy) } pthread_mutex_unlock(&g_mutex); } return m_instance;}
4.懒汉 静态对象,保证只有一个,不用new,不需要析构
template <class T>class singleton3{protected: singleton3(){};private: singleton3(const singleton3&){}; singleton3& operator=(const singleton3&){}; static pthread_mutex_t g_mutex;public: static T* GetInstance();};template <class T>T* singleton3<T>::GetInstance() { pthread_mutex_lock(&g_mutex); static T _instance; pthread_mutex_unlock(&g_mutex); return &_instance;}template <class T>pthread_mutex_t singleton3<T> ::g_mutex = PTHREAD_MUTEX_INITIALIZER;
5.测试函数
#include "pthread.h"#include <stdlib.h>#include <iostream>class ApplicationImpl{public: ApplicationImpl() { std::cout << "ApplicationImpl ..." << std::endl; } ~ApplicationImpl() { std::cout << "~ApplicationImpl ..." << std::endl; } void Run() { std::cout << "Run ..." << std::endl; }}; typedef singleton3 < ApplicationImpl > Application; void *routine(void *arg) { Application::GetInstance()->Run(); }int main(void) { Application::GetInstance()->Run(); pthread_t tid; int ret; if ((ret = pthread_create(&tid, NULL, routine, NULL)) != 0) { fprintf(stderr, "pthread create: %s\n", strerror(ret)); exit(EXIT_FAILURE); } Application::GetInstance()->Run(); pthread_join(tid, NULL); // Application::Destroy(); //第一个需要显示调用 return 0; }
以上程序的几点说明:
1.静态成员与类本身相关,不是对象(成员函数不能声明const,不能用this指针)。可用返回类类型,普通只能是类&或类*,可使用静态成员作为默认实参
2.在类外部定义静态成员不能重复static关键字
3.静态成员函数可以在类内/外定义(内部是内联的)
静态成员不是构造函数初始化的,一般不再内部初始化,const类型需要在内部初始化时,也应该在类外部定义下
4.const未初始化的,要在构造函数显示初始化
5.A a;默认构造函数,不需手动事发昂,析构函数自动执行
A= New A(); 只有delete释放,堆,一次初始化多次使用,可做返回等,不适合频繁调用
A* a=NULL; 普通指针,未经过初始化,不需delete
模板:
禁止继承的类
通过友元+虚继承实现。F是N的友元,可以调用N的私有初始化函数,F可以构造,若M要继承F,由于F是虚继承,里边直接包含N的虚表,会直接调用N的构造函数为private报错。若F不是虚继承,F的函数内会绑定N的构造函数在F内,友元可以调用
template<typename T>class NoneInherit { friend T;private: NoneInherit() { } ~NoneInherit() { }};class Finalclass: virtual public NoneInherit<Finalclass> {public: Finalclass() { } ~Finalclass() { }};
虚函数:
若用基类指针,赋值子类对象的方法调用,对于没有声明被声明成虚函数的方法,代码中的调用在编译时就已经被绑定了实现,绑定的是基类的实现。虚函数会增加一个vftable虚函数表,在动态运行时调用。
虚继承:
若出现菱形继承,D->B虚继承,C虚继承->A,D会因为B,C共同继承A有公共的一些成员变量和方法是相同的。如果用A指针指向D类的实例,则对于共同的成员变量和方法,编译器无法判断是要使用B类中的还是使用C类中的。增加虚指针,虚继承的成员由D直接访问A的。
非虚继承
class LandAnimal size(12):1> +---1> 0 | +--- (base class Animal)1> 0 | | {vfptr}1> 4 | | name1> | +---1> 8 | numLegs1> +---1>1> LandAnimal::$vftable@:1> | &LandAnimal_meta1> | 01> 0 | &Animal::breathe1> 1 | &LandAnimal::run1>1> class Mammal size(12):1> +---1> 0 | +--- (base class Animal)1> 0 | | {vfptr}1> 4 | | name1> | +---1> 8 | numBreasts1> +---1>1> Mammal::$vftable@:1> | &Mammal_meta1> | 01> 0 | &Animal::breathe1> 1 | &Mammal::milk1>1> class Human size(28):1> +---1> 0 | +--- (base class Mammal)1> 0 | | +--- (base class Animal)1> 0 | | | {vfptr}1> 4 | | | name1> | | +---1> 8 | | numBreasts1> | +---1> 12 | +--- (base class LandAnimal)1> 12 | | +--- (base class Animal)1> 12 | | | {vfptr}1> 16 | | | name1> | | +---1> 20 | | numLegs1> | +---1> 24 | race1> +---1>1> Human::$vftable@Mammal@:1> | &Human_meta1> | 01> 0 | &Animal::breathe1> 1 | &Human::milk1>1> Human::$vftable@LandAnimal@:1> | -121> 0 | &Animal::breathe1> 1 | &Human::run
虚继承:
1> class LandAnimal size(20):1> +---1> 0 | {vfptr}1> 4 | {vbptr}1> 8 | numLegs1> +---1> +--- (virtual base Animal)1> 12 | {vfptr}1> 16 | name1> +---1>1> LandAnimal::$vftable@LandAnimal@:1> | &LandAnimal_meta1> | 01> 0 | &LandAnimal::run1>1> LandAnimal::$vbtable@:1> 0 | -41> 1 | 8 (LandAnimald(LandAnimal+4)Animal)1>1> LandAnimal::$vftable@Animal@:1> | -121> 0 | &Animal::breathe1>1> class Mammal size(20):1> +---1> 0 | {vfptr}1> 4 | {vbptr}1> 8 | numBreasts1> +---1> +--- (virtual base Animal)1> 12 | {vfptr}1> 16 | name1> +---1>1> Mammal::$vftable@Mammal@:1> | &Mammal_meta1> | 01> 0 | &Mammal::milk1>1> Mammal::$vbtable@:1> 0 | -41> 1 | 8 (Mammald(Mammal+4)Animal)1>1> Mammal::$vftable@Animal@:1> | -121> 0 | &Animal::breathe1>1> class Human size(36):1> +---1> 0 | +--- (base class Mammal)1> 0 | | {vfptr}1> 4 | | {vbptr}1> 8 | | numBreasts1> | +---1> 12 | +--- (base class LandAnimal)1> 12 | | {vfptr}1> 16 | | {vbptr}1> 20 | | numLegs1> | +---1> 24 | race1> +---1> +--- (virtual base Animal)1> 28 | {vfptr}1> 32 | name1> +---1>1> Human::$vftable@Mammal@:1> | &Human_meta1> | 01> 0 | &Human::milk1>1> Human::$vftable@LandAnimal@:1> | -121> 0 | &Human::run1>1> Human::$vbtable@Mammal@:1> 0 | -41> 1 | 24 (Humand(Mammal+4)Animal)1>1> Human::$vbtable@LandAnimal@:1> 0 | -41> 1 | 12 (Humand(LandAnimal+4)Animal)1>1> Human::$vftable@Animal@:1> | -281> 0 | &Human::breathe