c++ learn
1指针
2静态成员和静态成员函数
我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。
静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化。
如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。
静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
静态成员函数有一个类范围,他们不能访问类的 this 指针。您可以使用静态成员函数来判断类的某些对象是否已被创建。
静态成员函数与普通成员函数的区别:
静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
#include <opencv2/opencv.hpp>
#include<time.h>
#include "car_clasfy.h"
#include "cfldwp_wrap.h"
#include<iostream>
using namespace std;
car_clasfy *car_clasfy::handle=nullptr;
car_clasfy *car_clasfy::instance(){
return handle;
}
bool Paricompare(const std::pair<float,int>&l,const std::pair<float,int>&r)
{
return l.first>r.first;
}
vector<int> Argmax(const vector<float>&v,int N)
{
vector<std::pair<float,int> >paris;
for (int i=0;i<v.size();i++)
paris.push_back(make_pair(v[i],i));
partial_sort(paris.begin(),paris.begin()+N,paris.end(),Paricompare);
vector<int> result;
for(int i=0;i<N;i++)
{
result.push_back(paris[i].second);
}
return result;
}
car_clasfy::car_clasfy(){}
car_clasfy::~car_clasfy(){}
car_clasfy *car_clasfy::instance(int thread_n,const vector<int>&gpus,
const std::string &model_dir)
{
if(handle==nullptr){
handle=new car_clasfy();
handle->init(thread_n,gpus);
}
return handle;
}
void car_clasfy::uninstance(){
if (handle==nullptr)
return;
delete handle;
handle=nullptr;
}
void car_clasfy::init(int thread_n,const vector<int> &gpu_ids)
{
auto odt=cfldwp::mod("car_clasfy");
odt->set_pixel_mean(cv::Scalar(104,117,123));
return;
}
void car_clasfy::detect(vector<Mat> &img_list,vector<int>& result)
{
for (int i=0;i<img_list.size();i++)
{
cv::Mat img=img_list[i];
clock_t start,end;
auto odt1=cfldwp::mod("car_clasfy");
odt1->set_pixel_mean(cv::Scalar(104,117,123));
start=clock();
auto odt_out=odt1->sync_proc_i0({img},{"prob"});
auto& output= odt_out[0].data;
end=clock();
cout<<"execution time ="<<(double)(end-start)/CLOCKS_PER_SEC<<endl;
vector<int> maxn=Argmax(output,1);
result.push_back(maxn[0]);
}
}
可以看出静态成员函数只能访问静态成员,而静态成员可以访问类内的所有成员
#include"interface.h"
#include"car_clasfy.h"
using namespace std;
using namespace cv;
void processinit(const char* model_path,const vector<int> gpus)
{
std::string mod_json_template = "{\"base_dir\":\"\","
"\"mods\" : [{\"name\":\"car_clasfy\", \"type\":\"cafl\", \"gpus\" : [0], \"modpath\" : \"./model/_iter_750000.caffemodel\", \"protpath\" : \"./model/deploy.prototxt\"}]}";
cfldwp::load_mod_cfg_json(mod_json_template.data());
cfldwp::wait_init_done();
car_clasfy::instance(1,gpus,model_path);
return;
}
void processrelease()
{
car_clasfy::uninstance();
return;
}
void process(vector<Mat>& img_list,vector<int>& result)
{
car_clasfy* handle=car_clasfy::instance();
handle->detect(img_list,result);
}
可以看出类外调用成员函数,可以直接类名::静态成员函数,不需要先申请类对象。
3虚拟函数
这静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为函数在程序编译期间就已经设置好了。
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。更加详细的内容见菜鸟教程多态