| ■ Probelm definition_____________________________________________
I'm trying to design a super-flexible, but memory efficient module, having several members that are ON/OFF-switchable respectably depending on the situation.
Which variables the module will own should be determined at the run-time.
I somehow made similar one working at the compile-time, using macros and enumerator flags :
▼ TraitSwitch.h
#pragma once
// Macros to switch-off source codes themselves.
#define ON 1
#define OFF 0
#define TRI_AREA_INFO ON
#define TRI_CENTROID_INFO ON
#define TRI_NORMAL_INFO OFF
...
▼ TriangleTraits.h
#pragma once
#include <cstdint>
#include "TraitSwitch.h"
enum TriangleTrait : uint8_t
{
NONE = 0, // 0000 0000
#if (TRI_AREA_INFO == ON)
AREA = 1, // 0000 0001
#endif
#if (TRI_CENTROID_INFO == ON)
CENTROID = 2, // 0000 0010
#endif
#if (TRI_NORMAL_INFO == ON)
NORMAL_VECTOR = 4, // 0000 0100
#endif
... // more traits
ALL = 255 // 1111 1111
}
// Need some additional overloaded bitwise-operators (&, |, |=, etc ...)
▼ Triangle.h
#pragma once
#include "TriangleTraits.h"
class Triangle
{
public:
Triangle() {}
~Triangle() {}
#if (TRI_AREA_INFO == ON)
double area;
#endif
#if (TRI_CENTROID_INFO == ON)
double centroid[3]; // x, y, z
#endif
#if (TRI_NORMAL_INFO == ON)
double normal[3]; // x, y, z
#endif
...
TriangleTrait alreadyComputed; // To avoid redundant works.
void ComputeTraits(TriangleTrait _trait)
{
if (((_trait & TriangleTrait::AREA) != 0)
&& ((_trait & alreadyComputed) == 0))
{
this->ComputeArea();
alreadyComputed |= TriangleTrait::AREA;
}
... // do the same things for centroid, normal
}
private:
void ComputeArea();
void ComputeCentroid();
void ComputeNormal();
...
}
then, Ctrl + SpaceBar(C++ IntelliSense) on the object may show : this
▼ main.cpp
#include <iostream>
#include "Triangle.h"
int main(void)
{
Triangle tri;
tri.ComputeTraits(TriangleTrait::AREA | TriangleTrait::CENTROID);
std::cout << "area : " << tri.area << "m²" << std::endl;
std::cout << "centroid : ("
<< tri.centroid[0] << ","
<< tri.centroid[1] << ","
<< tri.centroid[2] << ")" << std::endl;
}
Firstly Triangle.h looks quite ugly, and even if it looks good, this method determines class members at the compile-time, anyway.
| ■ Question summary_____________________________________________
"How to design a (template-)class with switchable members, which are determined at the run-time."
Here's the very thing what I want :
▼ main.cpp
...
int main(void)
{
Triangle<__MACRO_DEFINED_TRAIT_SWITCH(AREA)> tri1; // This owns area info only
Triangle<__MACRO_DEFINED_TRAIT_SWITCH(AREA | CENTROID)> tri2; // This owns area & centroid info
Triangle<__MACRO_DEFINED_TRAIT_SWITCH(AREA | CENTROID | NORMAL)> tri3; // This owns area & centroid & normal vector info
}
I guess using templates combined with macros (with Tag-dispatching method, maybe?) will do exactly what I want, but have no any clear idea.
Aucun commentaire:
Enregistrer un commentaire