/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
En interval klasse
Fra : Ken Frøslev


Dato : 12-07-02 08:34

Hej,

Jeg har forsøgt at lave en "interval" klasse, som begrænser en type til et
bestemt interval [min;max]. Problemet er at intervallet bestemmes når der
oprettes et nyt object, men jeg vil gerne have intervallet tilknyttet typen.
Er der nogen der har et godt forslag?

template<typename T>
class value_control {
public:
value_control(T v, T min, T max) : max_(max), min_(min) { value_ =
norm(v);}
operator T() {return value_;}

private:
T value_;
const T max_;
const T min_;
T norm(T& v) {
if (v > max_)
v = max_;
if(v < min_)
v = min_;
return v;
}
};

Mvh Ken



 
 
Mogens Hansen (12-07-2002)
Kommentar
Fra : Mogens Hansen


Dato : 12-07-02 11:03

"Ken Frøslev" <Ken@Froslev.dk> wrote

[snip]
> Er der nogen der har et godt forslag?

Såfremt T er en helttals type (eller en enum) kan man skrive:

template <typename T, T min, T max>
class value_control
{
public:
value_control(const T& value) :
value_(norm(value)) {}

operator T() const
{ return value_; }

private:
static T norm(const T& value)
{
if(value > max) return max;
if(value < min) return min;
return value;
}

private:
T value_;

};

int main()
{
value_control<int, 1, 7> i_1_7(1);
}


Bemærk at funktionen "norm" er static, og måske er kandidat til at blive
lagt i en selvstændig hjælpeklasse/hjælpefunktion, som så kunne gives med
som template argument.
Det kunne dels give lidt større fleksibilitet i udvalget af typer (f.eks.
"float" og "std::string") og dels give større fleksibilitet med hensyn til
hvad der skal ske når værdien kommer uden for det tilladte interval (f.eks.
trunkere, smide en exception, wrappe rundt)

Venlig hilsen

Mogens Hansen



Ken Frøslev (12-07-2002)
Kommentar
Fra : Ken Frøslev


Dato : 12-07-02 15:57

Hej igen,

Men at factory pattern kan man lave noget der luget lidt af fisk.Men jeg vil
stadigvæk gerne hører hvis der er nogen der har en bedre ide til hvordan man
kan lave en egentlig type.

Mvh Ken

Program:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

template<class T> class creator;

template<typename T>
class value_control {
public:
operator T() {return value_;}
operator=(const value_control& other) {
min_ = other.min_;
max_ = other.max_;
value_ = other.value;
}
T& operator=(const T& v) {
value_ = norm(v);
//return *this;
}

private:
friend creator<T>;
value_control(T v, T min, T max)
: min_(min), max_(max) { value_ = norm(v); }
private:
T value_;
T max_;
T min_;
T norm(T& v) {
if (v > max_)
v = max_;
if(v < min_)
v = min_;
return v;
}
};

template<typename T>
class creator
{
public:
creator(T min, T max) : min_(min), max_(max) {}
value_control<T> Create(T value = T()) {
return value_control<T>(value, min_, max_);
}
private:
T min_;
T max_;
};

int main(int argc, char* argv[])
{
creator<int> c(1, 5);

value_control<int> vc1 = c.Create(2);
value_control<int> vc2 = c.Create(8);
value_control<int> vc3 = c.Create();

cout << "vc1: " << vc1 << endl;
cout << "vc2: " << vc2 << endl;
cout << "vc3: " << vc3 << endl;

vc3 = vc1 + 5;
vc2 = vc2 * 2;

cout << endl;
cout << "vc1: " << vc1 << endl;
cout << "vc2: " << vc2 << endl;
cout << "vc3: " << vc3 << endl;

creator<string> cre("a", "z");
value_control<string> vc_1_str = cre.Create();
cout << static_cast<string>(vc_1_str) << endl;
value_control<string> vc_2_str = cre.Create("b");
cout << static_cast<string>(vc_2_str) << endl;

char ch;
cin >> ch;

return 0;
}





Mogens Hansen (12-07-2002)
Kommentar
Fra : Mogens Hansen


Dato : 12-07-02 19:18


"Ken Frøslev" <Ken@Froslev.dk> wrote

> Men at factory pattern kan man lave noget der luget lidt af fisk.Men jeg
vil
> stadigvæk gerne hører hvis der er nogen der har en bedre ide til hvordan
man
> kan lave en egentlig type.

Det væsentlige problem ved min tidligere løsning, var vel at den kun virkede
for heltal og enum's.

Hvis det skal være en egentlig type (så integer i området 1-7 er en anden
type end integer i området 2-8), så skal måden at specificere grænserne på
formodentlig indgå i type beskrivelsen (som template parametre).
Man kan bruge en peger til en funktion til det formål:
(selvom der indgår pointere til funktioner, kan det hele inlines)

<code>
#include <string>

using namespace std;

template <typename T, T (*Norm)(const T& value)>
class value_control
{
public:
value_control(const T& value) :
value_((*Norm)(value)) {}

operator T()
{ return value_; }

private:
T value_;
};

template <typename T>
inline T range_normalize(const T& value, const T& min, const T& max)
{
if(value > max) return max;
if(min > value) return min;
return value;
}

inline int norm_int_1_7(const int& value)
{
return range_normalize(value, 1, 7);
}

inline string norm_string_a_k(const string& value)
{
static const string min("a");
static const string max("k");
return range_normalize(value, min, max);
}

inline double norm_angle(const double& angle)
{
double result = angle;
while(result > 360) result -= 360;
return result;
}

int main()
{
typedef value_control<int, norm_int_1_7> int_1_7;
int_1_7 i(8);

typedef value_control<string, norm_string_a_k> string_a_k;
string_a_k s1("in range!");
string_a_k s2("out of range!");

typedef value_control<double, norm_angle> angle;
angle a(100.0);
while(a > 25) {
a = a + 25;
}
}

</code>

Andre bud og kommentarer er naturligvis velkomne.

Venlig hilsen

Mogens Hansen



Søg
Reklame
Statistik
Spørgsmål : 177496
Tips : 31968
Nyheder : 719565
Indlæg : 6408491
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste