Policy based design

M

Martin Vorbrodt

I'm designing a Matrix class of 4x4 matrices used in computer graphics. Both
OpenGL and Direct3D can take a pointer to array of 16 floats which represent
the values in the matrix. OGL takes it in column order, D3D in row order.
Therefore row = 2, col = 3 will result in different offset into the float
array depending on the API. Here is my basic design test program:

#include <iostream>
using std::cout;
using std::endl;

class OGLOffset {
public:
inline int GetOffset(int row, int col) const {
cout << "OGL offsets (" << row << "," << col << ") = ";
return row + col * 4;
}
};

class D3DOffset {
public:
inline int GetOffset(int row, int col) const {
cout << "D3D offsets (" << row << "," << col << ") = ";
return col + row * 4;
}
};

template<typename T, typename OffsetPolicy>
class Matrix {
public:
inline int GetOffset(int row, int col) const
{ return Offset.GetOffset(row, col); }

private:
OffsetPolicy Offset;
};

int main() {
Matrix<int, OGLOffset> m1;
Matrix<int, D3DOffset> m2;

cout << m1.GetOffset(2, 3) << endl;
cout << m2.GetOffset(2, 3) << endl;
}

Now my question is this:

In this example, i use inline functions, and the matrix class has-a object
of a given offseting policy type. What i could do instead, is to have a
static member function instead, and NOT keep a copy of the policy class
inside the matrix. Which approach would be better? I can see the basic
tradeoff: inline member is probably "faster", but there is storage overhead
for having OffsetPolicy member (no class can have a size of 0, according to
the standard right?) On the other hand, static costs me 0 space overhead.
But is it slower? Does it require an additional function call (even though
the body of the static is visible)?

Please advise. I'm new to the policy based deisgn. I know STL makes
extensive use of such approaches (allocators, traits, etc). Please point me
to information (i'm in the process of reading Modern C++ Design, by
Alexandrescu), i would like to get as much info as possible on this kind
ofdesign approaches.

Thanks in advance!

Martin
 
M

Martin Vorbrodt

One more thing. What about inheritance? I saw an approach where the host
class inherits from the policy class.
 
V

Victor Bazarov

Martin said:
I'm designing a Matrix class of 4x4 matrices used in computer graphics. Both
OpenGL and Direct3D can take a pointer to array of 16 floats which represent
the values in the matrix. OGL takes it in column order, D3D in row order.
Therefore row = 2, col = 3 will result in different offset into the float
array depending on the API. Here is my basic design test program:

#include <iostream>
using std::cout;
using std::endl;

class OGLOffset {
public:
inline int GetOffset(int row, int col) const {
cout << "OGL offsets (" << row << "," << col << ") = ";
return row + col * 4;
}
};

class D3DOffset {
public:
inline int GetOffset(int row, int col) const {
cout << "D3D offsets (" << row << "," << col << ") = ";
return col + row * 4;
}
};

template<typename T, typename OffsetPolicy>
class Matrix {
public:
inline int GetOffset(int row, int col) const
{ return Offset.GetOffset(row, col); }

private:
OffsetPolicy Offset;
};

int main() {
Matrix<int, OGLOffset> m1;
Matrix<int, D3DOffset> m2;

cout << m1.GetOffset(2, 3) << endl;
cout << m2.GetOffset(2, 3) << endl;
}

Now my question is this:

In this example, i use inline functions, and the matrix class has-a object
of a given offseting policy type. What i could do instead, is to have a
static member function instead, and NOT keep a copy of the policy class
inside the matrix. Which approach would be better?

A static function is definitely preferable. And WRT your approach, you
don't have to keep the copy of the policy object, you could always use
a temporary:

inline int GetOffset(int row, int col) const
{
return OffsetPolicy().GetOffset(row, col);
}

, if for some reason a static member doesn't work out for you. It does
carry a tiny overhead of creating a temporary object and passing its
pointer to the member function, of course (unlike the static member).
> I can see the basic
tradeoff: inline member is probably "faster", but there is storage overhead
for having OffsetPolicy member (no class can have a size of 0, according to
the standard right?) On the other hand, static costs me 0 space overhead.
But is it slower?
No.

> Does it require an additional function call (even though
the body of the static is visible)?
No.

[..]

V
 
V

Victor Bazarov

Martin said:
One more thing. What about inheritance? I saw an approach where the host
class inherits from the policy class.

Please don't top-post, even in response to your own messages.

What about inheritance? Did you mean to ask a particular question? Yes,
Alexandrescu in his book shows plenty of examples of classes inheriting
from policies...

V
 
M

Martin Vorbrodt

Victor Bazarov said:
Martin said:
One more thing. What about inheritance? I saw an approach where the host
class inherits from the policy class.

Please don't top-post, even in response to your own messages.

What about inheritance? Did you mean to ask a particular question? Yes,
Alexandrescu in his book shows plenty of examples of classes inheriting
from policies...

V

Do you know what the advantages would be of using inheritance for policy
classes? Why not statics, or policy class as a data member?
 
V

Victor Bazarov

Martin said:
Martin said:
One more thing. What about inheritance? I saw an approach where the host
class inherits from the policy class.

Please don't top-post, even in response to your own messages.

What about inheritance? Did you mean to ask a particular question? Yes,
Alexandrescu in his book shows plenty of examples of classes inheriting
from policies...


V


Do you know what the advantages would be of using inheritance for policy
classes? Why not statics, or policy class as a data member?

The advantage is you provide your 'GetOffset' only once -- in the policy,
and there is no need for another member, in the actual class. Why not?
A policy as a data member wastes memory. Statics, sure, why not?

V
 
A

Axter

Martin said:
I'm designing a Matrix class of 4x4 matrices used in computer graphics. Both
OpenGL and Direct3D can take a pointer to array of 16 floats which represent
the values in the matrix. OGL takes it in column order, D3D in row order.
Therefore row = 2, col = 3 will result in different offset into the float
array depending on the API. Here is my basic design test program:

#include <iostream>
using std::cout;
using std::endl;

class OGLOffset {
public:
inline int GetOffset(int row, int col) const {
cout << "OGL offsets (" << row << "," << col << ") = ";
return row + col * 4;
}
};

class D3DOffset {
public:
inline int GetOffset(int row, int col) const {
cout << "D3D offsets (" << row << "," << col << ") = ";
return col + row * 4;
}
};

template<typename T, typename OffsetPolicy>
class Matrix {
public:
inline int GetOffset(int row, int col) const
{ return Offset.GetOffset(row, col); }

private:
OffsetPolicy Offset;
};

int main() {
Matrix<int, OGLOffset> m1;
Matrix<int, D3DOffset> m2;

cout << m1.GetOffset(2, 3) << endl;
cout << m2.GetOffset(2, 3) << endl;
}

Now my question is this:

In this example, i use inline functions, and the matrix class has-a object
of a given offseting policy type. What i could do instead, is to have a
static member function instead, and NOT keep a copy of the policy class
inside the matrix. Which approach would be better? I can see the basic
tradeoff: inline member is probably "faster", but there is storage overhead
for having OffsetPolicy member (no class can have a size of 0, according to
the standard right?) On the other hand, static costs me 0 space overhead.
But is it slower? Does it require an additional function call (even though
the body of the static is visible)?

Please advise. I'm new to the policy based deisgn. I know STL makes
extensive use of such approaches (allocators, traits, etc). Please point me
to information (i'm in the process of reading Modern C++ Design, by
Alexandrescu), i would like to get as much info as possible on this kind
ofdesign approaches.

Thanks in advance!

Martin

I recommend you inherit the policy. It's more efficient then the
member method, and IMHO, easier to maintain and read then the static
method.

Example:
template<typename T, typename OffsetPolicy>
class Matrix : public OffsetPolicy {
public:
// No need for the following code, since you inheritance the method
from base class
// inline int GetOffset(int row, int col) const
// { return GetOffset(row, col); }
};

FYI:
This does not follow the IS-A rule for inheritance, but policy classes
are the exception to the (IS-A) rule.
 
M

Martin Vorbrodt

Axter said:
I recommend you inherit the policy. It's more efficient then the
member method, and IMHO, easier to maintain and read then the static
method.

Example:
template<typename T, typename OffsetPolicy>
class Matrix : public OffsetPolicy {
public:
// No need for the following code, since you inheritance the method
from base class
// inline int GetOffset(int row, int col) const
// { return GetOffset(row, col); }
};

FYI:
This does not follow the IS-A rule for inheritance, but policy classes
are the exception to the (IS-A) rule.

so i hear!
make the destructor private and non virtual should take care of is-a.

ufff, cool shit! c++ rules!
 
M

mlimber

Axter said:
I recommend you inherit the policy. It's more efficient then the
member method, and IMHO, easier to maintain and read then the static
method.
[snip]

I normally do this also. However, empty base classes (in this case,
policy classes without data members) are not always free and thus not
always more efficient in terms of memory usage. There is further
discussion of and a trick to get around the problem in the article
"Smart Pointers Reloaded" by Andrei Alexandrescu and David B. Held in
section entitled "Size Does Matter"
(http://www.cuj.com/documents/s=8890/cujexp0310alexandr/alexandr.htm).

Cheers! --M
 
P

Puppet_Sock

Martin Vorbrodt wrote:
[snip]
But is it slower?

Usually the answer to that question is "get out a stopwatch
and write a test code to try it." If you do, try to make it
as representative of typical situations as possible.

But before you do that, ask yourself if the "slower" that
might actually exist is going to make a big difference.
If you are talking about a part of your code where it
spends, say, 5 percent of its time, it's probably not
worth worrying about even if it *is* slower. If it's in
part of the code where it spends 90 percent of its time,
it might be worth it if there is a big difference. If you
worry about "is it slower" before you find out if it matters,
you are probably wasting your time.
Socks
 

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

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,113
Latest member
Vinay KumarNevatia
Top