terminator wrote:
Quote:
aaragon wrote:
Quote:
Hi everyone. I'm trying to write a class with policy based design
(Alexandrescu's Modern C++ Design). I'm not a programmer but an
engineer so this is kind of hard for me. Through the use of policies,
I want to customize the structure of a class. The idea is to
investigate the use of several data structures. One option would be
the use of the boost dynamic bitset. Another would be the use of the
std::vector. I obtained some code that is working and is shown below.
There are some things that I don't like about the code and that is the
reason I'm posting this message.
>
Dear aaragon:
>
i have veiwed your code listing .i am affraid
it looks to me that you are no c++ programer .
Indeed, I'm an engineer. However, I found in C++ an amazing tool so
I'm doing my best to learn the language.
Quote:
>
i do not claim to be professional
and i dont know Alexanderscue either
>
i did not understand what the program is intended to do
The class is intented to provide several data structures as a simple
option to the user. Then, I will be able to chose for example between
a dynamic bitset or a vector of boolean values. In this way I will be
able to compare performance between data structures.
Quote:
and i doubt that you can get a program
that satisfies your expectations
but assuming that you know what you are doing
i have the following recommendations for you:
>
you wrote:
Quote:
template <class T>
class StoragePolicy
{
public:
StoragePolicy();
StoragePolicy(size_t size_);
void print();
};
>
this portion of the code looks meaningless and error prone
remove or comment it out
I agree now so I did what you said.
Quote:
>
>
Quote:
1. In the current version, the user has to type
ClassA<double,VectorPolicyca(6);
to create an object of ClassA. I would like to change this to
ClassA<VectorPolicy<double ca(6);
>
>
you have defined the class as:
>
template
<
class T,
template <classclass StoragePolicy
>
class ClassA : public StoragePolicy<T>
{
>
>
this misses a '>' before 'class ClassA' and causes
the compiler not to compile the code, further more
this fraction of the code in its current state
(after adding the afformentioned missing '>')
compiles on microsoft platform but i am not sure that it
is standard and portable to other platforms such as
borland.
Yes, you were right but it was a copy error. I was able to compile the
code before I submitted the code in this post. I'm using SuSE Linux
v10.1 with the g++ compiler (version 4.x).
Quote:
therefore i agree with you in changing
the code to this:
>
template
<
class StoragePolicy
class ClassA : public StoragePolicy
{
>
then you have to type the code as:
>
ClassA<VectorPolicy<double ca(6);
>
Yes! Thank you, this is exactly what I wanted. I changed the code.
Quote:
but in order to have a more consistent code
optionally:
1. you can type
typedef T value_type;
after the first '{'
following 'struct VectorPolicy' and 'struct BitSetPolicy'
>
2.if and only if you did the first ,type
>
typedef typename StoragePolicy::value_type value_type;
>
after the first '{'
following 'class ClassA'
>
I don't see the purpose of doing this. What do you mean by more
consistent? I pasted the final version of the code in the end. If you
see the BitSetStorage, there is no point in having a templated
parameter (since the bitset is defined as boost::bitset<>). However, I
would like to know why you think the code is more consistent (I'm
learning so I appreicate any input).
Quote:
Quote:
2. The output of this code is as follows:
before instantiation of ca
default StoragePolicy constructor
Parameter constructor
after instantiation of ca
ClassA print()
VectorPolicy print()
before instantiation of cb
default StoragePolicy constructor
Parameter constructor
after instantiation of cb
I don't like the idea of instantiating the class with the default
constructor
>
you have Writen:
>
class ClassA : public StoragePolicy<T>
>
remove or comment out ' : public StoragePolicy<T>'
and the output will not contain:
default StoragePolicy constructor
>
Indeed, now that I know the right answer it seems obvious. In
Alexandrescu's book (1.10 Customizing Structure with Policy Classes) he
puts "Of course, SmartPtr must either derive from Storage<TOR
aggregate a Storage<Tobject in order to embed the needed structure".
He is taking about a smart pointer class that has a customized
structure through a storage policy class. I realize now that I was
doing both! (I was deriving from the storage class and aggregating an
object as well, and this I don't want). As you suggested, I removed
the inheritance part and now I have only the parameter constructor! =)
Quote:
alternatively if you have changed the code to what i wrote formerly
you can change the following:
>
ClassA(size_t size_) {
>
to:
ClassA(size_t size_):StoragePolicy(size_) {
>
otherwise to:
>
ClassA(size_t size_):StoragePolicy<T>(size_) {
>
this will lead to not only removing
>
default StoragePolicy constructor
>
from the output but also replacing it with another
>
Parameter constructor
About this point, the use of an initialization list isn't the same as
the code that I wrote in the beginning? The code that I have now is as
follows:
#include <iostream>
#include <vector>
#include <boost/dynamic_bitset.hpp>
using boost::dynamic_bitset;
using namespace std;
template <class T>
struct VectorPolicy
{
public:
typedef std::vector<TStructure;
VectorPolicy(size_t size_)
: str_(size_) {
cout<<"Parameter constructor"<<endl;
}
void print(){
cout<<"VectorPolicy print()"<<endl;
for(size_t i=0; i<str_.size(); i++)
cout<<str_[i];
}
private:
Structure str_;
};
struct BitSetPolicy
{
public:
typedef boost::dynamic_bitset<Structure;
BitSetPolicy(size_t size_)
: str_ ( size_ )
{
cout<<"Parameter constructor"<<endl;
}
void print(){
cout<<"BitSetPolicy print()"<<endl;
cout<<str_<<endl;
}
private:
Structure str_;
};
template
<
class StoragePolicy
class ClassA
{
StoragePolicy structure_;
public:
// parameter constructor
ClassA(size_t size_)
: structure_(size_)
{
;
}
// print function
void print()
{
cout<<"ClassA print()"<<endl;
structure_.print();
}
};
int main()
{
cout<<"before instantiation of ca"<<endl;
ClassA<VectorPolicy<double ca(6);
cout<<"after instantiation of ca"<<endl;
ca.print();
cout<<endl;
cout<<"before instantiation of cb"<<endl;
ClassA<BitSetPolicycb(6);
cout<<"after instantiation of cb"<<endl;
cb.print();
return 0;
}