What is the proper way of having static class members?
I am trying to create a metrics class so that I can include "metrics.h" in all of my files, and use certain variables from it (the static ones) to keep track of timing information across multiple separately compiled libraries.
One of these libraries is common to all of the other ones, so when I am com开发者_开发问答piling it, with metrics.h, it compiles fine, but when I am trying to compile one of the additional libraries that uses common, I get "multiple definition" errors, as well as some undefined references.
What should this common metrics class look like? I dont want to have to instantiate it to user the variables, I just want to use something like
Metrics::startTime = ....
and Metrics::calcTime = ....
in either the common library, or one of theo ther libraries that links to common
Instead of defining a number of static members, it might be better to package them all into one static struct
member.
Even better than directly instantiating and accessing this static member is hiding it inside a getter function.
class metrics {
...
struct measurements { // struct may be private; you can still access
double startTime; // the members of the result of the getter fn.
double calcTime;
...
};
public:
static measurements &getMeasurements() {
static measurements instance;
return instance;
}
};
With this, you don't need to add anything to the .cpp
file. The measurements
object instance
is created the first time getMeasurements
is called, and the same object is returned for all subsequent calls.
In the header file:
class Metrics {
public:
static int startTime ;
} ;
In exactly one cpp
file:
int Metrics::startTime ;
// metrics.hpp
class metrics {
static int i; // declaration
};
// metrics.cpp
int metrics::i(0); // definition
beyond that, it's all proper implementation of constructors
You should not be combining libraries in such a way that the same code ends up getting linked into a program more than once. Isolate your metrics class in one library, along with whatever other classes it should be packaged with (see the six packaging principles published by Robert Martin for guidance). Put your other classes that depend on it in other libraries (or put it all in one library if those packaging principles reveal that they belong together). When linking a program, link in all of the libraries required, including libraries that depend on the metrics class and the (one) library that contains the metric class.
Metrics.h
#ifndef _METRICS_H
#define _METRICS_H
class Metrics {
...
public:
Metrics();
//declare the static variables in the header for the class
static int startTime;
static int calcTime;
}
#endif
Metrics.cpp
#include "Metrics.h"
Metrics::Metrics(){
...
}
//define and initialize the variables in the implementation of the class
int Metrics::startTime = 15;
int Metrics::calcTime = 20;
main.cpp
#include "Metrics.h"
int main(){
//use the static variables elsewhere
int a = Metrics::startTime;
}
精彩评论