templates & classes

C

chameleon

I have 2 classes with exactly the same members (all static except
dtor/ctor).
Classes have different implementantion in only one static member
function and first class has one more member function.

How can I write this code with templates?
First of all: Thought to write code with templates is correct?

members of classes are static because refer to devices. There is no
reason to be non-static.

Thanks.

2 classes follow:
------------------
class ALDevices
{
static std::vector<std::string> lstDevices;
// AND MOOOOOORE STATICs SHARED IN 2 CLASSES!

public:
ALDevices(); // IMPLEMENTENT DIFFERENT IN 2 CLASSES
static void closeDevice(); // IMPLEMENTENT DIFFERENT IN 2 CLASSES

static int getTotalDevices() { return lstDevices.size(); }
// AND MOOOOOORE STATICs SHARED IN 2 CLASSES!

static ALCcontext *getActiveContext() { return context; } // DOEN'T
EXIST AT ALL IN SECOND CLASS
};
------------------
class ALCaptureDevices
{
static std::vector<std::string> lstDevices;
// AND MOOOOOORE STATICs SHARED IN 2 CLASSES!

public:
ALCaptureDevices(); // IMPLEMENTENT DIFFERENT IN 2 CLASSES
static void closeDevice(); // IMPLEMENTENT DIFFERENT IN 2 CLASSES

static int getTotalDevices() { return lstDevices.size(); }
// AND MOOOOOORE STATICs SHARED IN 2 CLASSES!
};
------------------
 
M

Markus Moll

Hi
I have 2 classes with exactly the same members (all static except
dtor/ctor).
Classes have different implementantion in only one static member
function and first class has one more member function.

How can I write this code with templates?
First of all: Thought to write code with templates is correct?

members of classes are static because refer to devices. There is no
reason to be non-static.

Two suggestions:
1. Redesign your program ;-)
2. Build a class template parameterized by a single type, put all
duplicated members in here. Derive both your classes from the
instantiations of this class template for the respective class.

Markus
 
P

Pete Becker

chameleon said:
I have 2 classes with exactly the same members (all static except
dtor/ctor).
Classes have different implementantion in only one static member
function and first class has one more member function.

How can I write this code with templates?
First of all: Thought to write code with templates is correct?

Seems like overkill. Put all the common stuff into a class, and write
two derived classes.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
C

chameleon

O/H Pete Becker Ýãñáøå:
Seems like overkill. Put all the common stuff into a class, and write
two derived classes.

The problem here is that: All common stuff is static members.
I want 2 template instantiations, so, 2 static member instances.

If I derive 2 classes from one, both classes share common static members.
 
V

Victor Bazarov

chameleon said:
O/H Pete Becker Ýãñáøå:

The problem here is that: All common stuff is static members.

Why is it a problem?
I want 2 template instantiations, so, 2 static member instances.
Why?

If I derive 2 classes from one, both classes share common static
members.

So?

V
 
P

Pete Becker

chameleon said:
O/H Pete Becker Ýãñáøå:

The problem here is that: All common stuff is static members.
I want 2 template instantiations, so, 2 static member instances.

If I derive 2 classes from one, both classes share common static members.

They share whatever you put in the base class, and they don't share
whatever you put in the derived classes. If it's not shared, don't put
it in the base.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
F

Fei Liu

Victor said:
Why is it a problem?


So?

V
The description of the OP's problem requires that 2 classes do not share
the storage of those static members. In this case, derivation won't
work. static class members can often be thought of as class member as
opposed to object member. The code as it is posted by the OP is fine. I
don't believe template will create any new solution. Check the example
code below:

#include <iostream>
using namespace std;

struct base{
static int x;
static int getx(){ return x;}
};

struct d1 : base {
static int getx(){ return x+1; }
static int xx(){ return x*x; }
};

struct d2 : base {
};

int base::x = 10;

int main(){
d1 a; d2 b;

cout << "d1::x = " << d1::getx() << " d2::x = " << d2::getx() << endl;
cout << "a.x = " << a.getx() << " b.x = " << b.getx() << endl;
a.x = 5;
cout << "d1::x = " << d1::getx() << " d2::x = " << d2::getx() << endl;
cout << "a.x = " << a.getx() << " b.x = " << b.getx() << endl;
d1::x = 15;
cout << "d1::x = " << d1::getx() << " d2::x = " << d2::getx() << endl;
cout << "a.x = " << a.getx() << " b.x = " << b.getx() << endl;

return 0;
}
 
P

Pete Becker

Fei said:
The description of the OP's problem requires that 2 classes do not share
the storage of those static members. In this case, derivation won't
work.

Of course it will. The things that aren't shared don't go in the base class.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
J

John Carson

chameleon said:
O/H Pete Becker Ýãñáøå:

The problem here is that: All common stuff is static members.
I want 2 template instantiations, so, 2 static member instances.

If I derive 2 classes from one, both classes share common static
members.

You can easily work around that with templates. A simple example follows.

template <int n>
class Base
{
static int x;
public:
static void Setx(int a_x)
{
x = a_x;
}
static int Getx()
{
return x;
}
};

template <int n>
int Base<n>::x;

class Derived1: public Base<0>
{
};

class Derived2: public Base<1>
{
};


int main()
{
Derived1 d1;
Derived2 d2;

d1.Setx(1);
d2.Setx(2);

cout << "Static member x of d1 is " << d1.Getx() << endl;
cout << "Static member x of d2 is " << d2.Getx() << endl;

return 0;
}
 
A

Alan Johnson

John said:
You can easily work around that with templates. A simple example follows.

template <int n>
class Base
{
static int x;
public:
static void Setx(int a_x)
{
x = a_x;
}
static int Getx()
{
return x;
}
};

template <int n>
int Base<n>::x;

class Derived1: public Base<0>
{
};

class Derived2: public Base<1>
{
};


int main()
{
Derived1 d1;
Derived2 d2;

d1.Setx(1);
d2.Setx(2);

cout << "Static member x of d1 is " << d1.Getx() << endl;
cout << "Static member x of d2 is " << d2.Getx() << endl;

return 0;
}

Your solution is correct, but requires assigning each derived class a
unique int. You could instead just directly use the derived class as
the template to the base:

template <class Derived>
class Base
{
static int x;
public:
static void Setx(int a_x)
{
x = a_x;
}
static int Getx()
{
return x;
}
};

template <class Derived>
int Base<Derived>::x;

class Derived1: public Base<Derived1>
{
};

class Derived2: public Base<Derived2>
{
};
 
J

John Carson

Alan Johnson said:
Your solution is correct, but requires assigning each derived class a
unique int. You could instead just directly use the derived class as
the template to the base:

template <class Derived>
class Base
{
static int x;
public:
static void Setx(int a_x)
{
x = a_x;
}
static int Getx()
{
return x;
}
};

template <class Derived>
int Base<Derived>::x;

class Derived1: public Base<Derived1>
{
};

class Derived2: public Base<Derived2>
{
};


Yes, much nicer. I like it :)
 
F

Fei Liu

Pete said:
Of course it will. The things that aren't shared don't go in the base
class.
It will what? The storage of derived classes is shared in base. The CRTP
solution posted in this thread is very nice though.
 
P

Pete Becker

Fei said:
It will what?

"In this case, derivation won't work."

"Of course it will.

What, specifically, do you claim "won't work"? Whatever is defined in
the base class is part of the base class, and whatever is defined in the
derived classes is part of the derived classes. So if you want the
derived classes to hold something in common, put it in the base class.
If you want the derived classes to hold independent things, put them in
the derived classes. The result is that the derived classes both have
whatever is in the base class, and each has whatever is defined for it.

struct base
{
static int i;
static void f();
};

struct derived1: base
{
static int j;
static void g();
};

struct derived2: base
{
static int k;
static void h();
};

Now, base has two members, i and f. derived1 has four members. It
inherits i and f from base, and it has the two in its definition, j and
g. derived2 has four members. It also inherits i and f from base, and it
has two in its definition, k and h.

So, once again: the members that are the same for both derived types
should be defined in base, and the members that are different should be
defined in their respective derived classes.
The storage of derived classes is shared in base. The CRTP
solution posted in this thread is very nice though.

Using templates where inheritance is more appropriate isn't "nice."

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
F

Fei Liu

Pete said:
"In this case, derivation won't work."

"Of course it will.

What, specifically, do you claim "won't work"? Whatever is defined in
the base class is part of the base class, and whatever is defined in the
derived classes is part of the derived classes. So if you want the
derived classes to hold something in common, put it in the base class.
If you want the derived classes to hold independent things, put them in
the derived classes. The result is that the derived classes both have
whatever is in the base class, and each has whatever is defined for it.

Clearly you don't understand the OP's spec, hint it's a device driver.
Your logical representation fails to meet the requirement of the
physical model.
struct base
{
static int i;
static void f();
};

struct derived1: base
{
static int j;
static void g();
};

struct derived2: base
{
static int k;
static void h();
};

Now, base has two members, i and f. derived1 has four members. It
inherits i and f from base, and it has the two in its definition, j and
g. derived2 has four members. It also inherits i and f from base, and it
has two in its definition, k and h.

So, once again: the members that are the same for both derived types
should be defined in base, and the members that are different should be
defined in their respective derived classes.


Using templates where inheritance is more appropriate isn't "nice."

Again you demonstrate that you do not understand the OP's problem.
 
P

Pete Becker

Fei said:
Clearly you don't understand the OP's spec, hint it's a device driver.
Your logical representation fails to meet the requirement of the
physical model.

On the contrary: I have read it carefully, and suggested an approach
that will do exactly what he said he wants.

Once again: what, specifically, do you claim "won't work"? No more
handwaving. Point out the exact problem, so that readers of this thread
will have a chance at understanding what it is that you think can't be
done through inheritance.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
J

John Carson

Pete Becker said:
On the contrary: I have read it carefully, and suggested an approach
that will do exactly what he said he wants.

Once again: what, specifically, do you claim "won't work"? No more
handwaving. Point out the exact problem, so that readers of this
thread will have a chance at understanding what it is that you think
can't be done through inheritance.


Speaking for myself, I didn't think much about the OP's spec, I just wanted
to answer the OP's question (just stating a fact here, not making a case).

My read was that the OP was mainly interested in code re-use. Thus the OP
didn't want identical lists of members in the derived classes. Using a
template to create two distinct bases was a way to get all those members
into the derived classes and make the static variables distinct, while only
typing them once (just why the OP wanted distinct static variables I don't
know).
 
P

Pete Becker

John said:
Speaking for myself, I didn't think much about the OP's spec, I just wanted
to answer the OP's question (just stating a fact here, not making a case).

Indeed. And you may have noticed that I didn't jump in and insist that
you're wrong. In fact, I suspect that a template may be the right answer
to the question that wasn't asked. But given the original problem
statement, all that's needed is to hoist one data member and one member
function into the derived class, and that doesn't call for a template.
Low-level design follows from actual specifications, not from guesses.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top