类的静态成员变量

Static member variable of a class

本文关键字:变量 静态成员      更新时间:2023-10-16

我有一个SVM分类器保存为"classifier.xml"。我从网络摄像头输入图像,并想对它们进行分类。因此,不是为每个输入图像加载分类器,我只是想只加载一次分类器(类似于静态),使用以下代码:

mySvm.load("classifier.xml");

问题:目前我已经声明了cv::SVM mySvm;作为全局变量,但我想摆脱全局变量。那么,我该怎么做才能使cv::SVM mySvm;成为Class Classifier的成员变量呢?

我的文件结构如下:

(1) classifier.h

class Classifier
{
    private:

    public:
        void getSvm();
};

(2) main.cpp

int main()
{
    Classifier objectSvm;
    objectSvm.getSvm();                     
}

(3) loadSVM.cpp

#include "classifier.h"
cv::SVM mySvm;
void svm::getSvm()
{
    mySvm.load("classifier.xml");
}

您可以使用静态成员变量并提供访问它的方法:

class Classifier
{
private:
    static cv::SVM svm;
public:
    void loadSvm(const char* fileName) { /* code for loading SVM */ }
    cv::SVM& getSVM() { return svm; }
};

成员函数loadSVM进行加载,getSVM简单地返回对变量的引用。

如果您担心用户多次加载SVM,则添加一个类型为bool的静态成员,该成员指示对象是否已加载。

class Classifier
{
private:
    static cv::SVM svm;
    static bool already_loaded = false; // required C++11
public:
    void loadSvm(const char* fileName)
    {
        if (already_initialized)
            return;
        // code for loading SVM
    }
    cv::SVM& getSVM() { return svm; }
};

然后像往常一样创建Classifier的实例并加载XML。

int main()
{
    Classifier c;
    c.loadSVM("foo.xml");
    // Whenever you want to use the SVM, go for member function `getSVM()`.
    // E.g. assuming the SVM has a `foo` member function:
    c.getSVM().foo();
}

(1) classifier.h

namespace cv { class SVM; }
class Classifier
{
    private:
        cv::SVM mySvm;
        void loadSvm();
    public:
        Classifier();
        void getSvm();
};

(3) loadSVM.cpp

#include "classifier.h"
void Classifier::loadSVM() {  mySvm.load("classifier.xml"); }
Classifier::Classifier() { /* loadSVM(); could load early */ }
void Classifier::getSvm() { loadSVM(); }

(2) main.cpp

int main()
{
    Classifier objectSvm;
    objectSvm.getSvm();   // loading happens on this line, as your example
                          // loading only shared for this instance of Classifier
    objectSvm.doSomething();
    objectSvm.doSomethingAgainWithSameClassifier();
    Classifier objectSvmAnother;
    objectSvmAnother.getSvm();  // load another classifier
    objectSvmAnother.doSomethingWithDifferentClassifierInstance();
}