I would like to eliminate duplicity of code in this problem:
class PopulationMember
{
public:
vector<int> x_;
vector<int> y_;
}
class Population
{
vector<PopulationMember*> members_;
void doComputationforX_1(); // uses the attribute x_ of all members_
void doComputationforX_2();
void doComputationforX_3();
void doComputationforY_1(); // exactly same as doComputationforX_1, but
void doComputationforY_2(); // uses the attribute y_ of all members_
void doComputationforY_3();
EDIT: // there are also functions that use all the members_ simultaniously
double standardDeviationInX(); // computes the standard deviation of all the x_'s
double standardDeviationInY(); // computes the standard deviation of all the y_'s
}
The duplicity is causing me to have 6 methods instead of 3. The pairwise similarity is so
striking, that I can get the implementation of doComputationforY_1 out of doComputationforX_1 by simply replacing the "x_" by "y_".
I thought about remaking the problem in this way:
class PopulationMember
{
public:
vector<vector<int>> data_; // data[0] == x_ and data[1] == y_
}
But it becomes less clear this way.
I know that a precompiler macro is a bad solution in general, but I do not see any other. My subconciousness keeps suggesting templates, but I just do not see how can I use them.
If you want to keep x_ and y_ separately in the same class PopulationMember then it's better to choose pass by value solution rather than template solution:
Define the generic method as:
void doComputationfor (vector<int> (PopulationMember::*member_));
// pointer to data ^^^^^^^^^^^^^^^^^^^^^^^^^^
Call it as:
doComputationfor(&PopulationMember::x_);
doComputationfor(&PopulationMember::y_);
Remember that if your doComputationfor is large enough then, imposing template method would make code duplication.
With the pointer to member method, you will avoid the code duplication with a little runtime penalty.
If the API you have specified is exactly what you want users of the class to see, then just make private methods in Population called doComputation_1( const vector<int> &v ) { do stuff on v; }
And then make the public implementations 1 line long:
public:
void DoComputationX_1() { doComputation_1( x_ ); }
void DoComputationY_1() { doComputation_1( y_ ); }
private:
// drop the 'const' if you will need to modify the vector
void doComputation_1( const vector<int> &v ) { do stuff on v; }
I don't feel like this is the right solution, but I can't piece together what your class is really trying to do in order to offer up anything more meaningful.
Related
This is in relation to an earlier question I had. I haven't managed to solve the problem there but for now I'm just trying to get better acquainted with the code to figure out how to deal with that problem.
Towards that goal, I've got around to trying out the suggestions given in that question and I'm a little stumped as to why the following isn't working.
in the header I have
class A {
public:
typedef std::multimap<int, double> intdoublemap_t;
const intdoublemap_t& getMap() const;
void setkey(int k);
void setvalue(double v);
void insertIntoMap();
intdoublemap_t mMapA;
private:
int key;
double value;
};
class B {
public:
typedef std::multimap<int, double> intdoublemap_t;
void mapValues(const A& a);
private:
intdoublemap_t mMapB;
};
in the implementation I have
const A::intdoublemap_t& A::getMap() const { return mMapA; }
void A::setkey(int k) { key = k; }
void A::setvalue(double v) { value = v; }
void A::insertIntoMap(){mMapA.insert(std::make_pair(key, value));}
void B::mapValues(const A & a){ const A::intdoublemap_t& mref = a.getMap();
mMapB = mref; }
and in main()
A a;
a.setkey(10);
a.setvalue(1232.2);
a.insertIntoMap();
B b;
b.mapValues(a);
The code compiles fine and everything to do with a works as expected but the map is not passing to b at all. It stays empty
Can anyone tell me why?
edit: I took another look at this and saw how to do it. I knew it was something stupidly basic. I just had to set mref in the function to a map in B and then could call a function to work on that map within B.
As #FrancoisAndrieux notes, your getMap() only sets a reference local to the function - not the class' intdoublemap_t mref. If you want the latter to be a reference to a map elsewhere, you have three options:
Make it intdoublemap_t& mref, initialize it on construction of the B instance.
Make it std::reference_wrapper<intdoublemap_t> mref, set it whenever you want (e.g. in mapValues().
Make it intdoublemap_t* (or std::shared_ptr<intdoublemap_t> in both A and B), set it whenever you like.
Note: As #FrancoisAndrieux says in a comment, with the second and third option (and without std::shared_ptr) you will have to be careful not to allow the reference to be used after the original object's lifetime has expired.
Having said all the above - I must also say that your design seems rather off to me. You should really not be doing any of these things and I'm 99% sure you're approaching your task the wrong way.
I am working with a large code base, and there are a number of publicly defined variables. Unfortunately, the functions of accessing these variables has changed, and this new functionality would be best encapsulated by public accessors and a private instance variable.
So, I am trying to make this change. To do so, I planned to make each public property private and then create accessors. But, I don't want to change any of the code which accesses the old public properties. For example:
After changing the public property to private, I have the following class:
class Test {
private:
int item = 5;
public:
int GetItem() {
return item;
};
void SetItem(int new_item) {
item = new_item;
};
};
In the past, "item" used to be a public property of the class, and it was accessed through:
Test* t = new Test();
int item = t->item;
Now though, I need to add new functionality to the way in which "item" is retrieved. For example:
int GetItem() {
// Some complicated code which changes "item"
return item;
};
How can I keep the same syntax:
int item = t->item;
But have this actually perform:
int item = t->GetItem();
Any help is greatly appreciated!
You can make int item = t.item; work, by defining item as a member variable whose type is a helper class with a custom conversion operator int() defined. Also, operator=(int new_value) to intercept the set operation.
What you can't make work is
int& item = t.item;
or
int* pitem = &t.item;
because both of these enable direct memory access, without going through any getter or setter. When creating the reference or pointer, you can't even determine how many accesses there will be or whether they will be reads or writes.
C++ is a compiled non-reflective language, i.e. you can't just "look names up as you access an element", because in the binary, there are no names anymore.
So, no, what you want is impossible. (at least not without restrictions – see Ben Voigt's excellent answer; having a "transparent" property which is in fact a getter call surely isn't worth the pitfalls you're building with that-)
Also, please don't let your C++ become Java just for the sake of having getters and setters – if they don't actually add security, I don't really see the point of using them
In case that your question is based in the fact that you don't want to call 2 different functions for setting and getting, you can make a function that returns a reference of the member:
int& Item()
{
// Some complicated code which changes *items
return item;
}
as you can see, the return type is int& instead of int. so you can use this function this way
t.Item() = someValue;
To expand on Ben Voight's answer, you can define a proxy template that allows this without the boiler plate:
template <typename Return, typename Containing, Return (Containing::* func)()>
struct proxy
{
Containing& c;
proxy(Containing& c) : c(c) {}
operator Return() { return (c.*func)(); }
Return& operator=(const Return& r) { return (c.*set)() = r; }
};
Then to define a "property"
class c {
int y_;
int get_y() { std::cout << "Getting y" << std::endl; return y_; }
public:
proxy<int, x, &x::get_y> y;
c() : y(*this) {}
};
And in client code
int main() {
c val;
val.y = 5;
std::cout << val.y << std::endl;
}
I am currently creating a class that has to be derived from std:: vector. I realize its probably bad to do this but I'm required to. Now my question is how do you access the created vector in the member functions to basically make the class access itself like a regular vector of integers? For example I am looking for the equivalent of myVector.at(0) to return the first term in the vector. Also, the size of the vector should always be 6. Here is the code I have so far:
class aHistogram : public vector<int>
{
public:
aHistogram(); //default constructor for histogram class
void update(int face); //Function to update histogram
void display(int maxLengthOfLine); //Displays histogram to the scale of maxLengthOfLine using x's
void clear();//Function to clear histogram bin counts
int count(int face) const; // Function to return number of times a face has appeared
private:
int numx, m, j; //Variables used in functions
};
#endif
The function that requires the class to access itself is below, I know there is no vector called "myVector" but what I'm lost about is the equivalent syntax to be able to perform the operation.
void aHistogram::clear()
{
//Clears bin counts to 0
myVector.at(0) = 0;
myVector.at(1) = 0;
myVector.at(2) = 0;
myVector.at(3) = 0;
myVector.at(4) = 0;
myVector.at(5) = 0;
}
If the function in question isn't overridden in the derived class, you
can just call it:
void HistoGram::clear()
{
at( 0 ) = 0;
// ...
}
This is also true for operators, but you'll have to use (*this) as the
left hand operator:
void HistoGram::clear()
{
(*this)[0] = 0;
// ...
}
If the function or operator is overridden, you'll either have to
qualify the function name,
void HistoGram::clear()
{
std::vector<int>::at( 0 ) = 0;
// ...
}
or cast the this pointer to the base class type:
void HistoGram::clear()
{
(*static_cast<std::vector<int>*>( this ))[0] = 0;
// ...
}
But are you sure that you want public inheritance here? You state that
the size of the vector should always be 6. There's no way you can
guarantee that using public inheritance; at the least, you need private
inheritance, and then using declarations for the operations that you
want to support. (I've a couple of cases where I've needed restricted
std::vector like this, which I've implemented using private
inheritance. And sometimes forwarding functions, when for example
I've wanted to expose only the const version of the function.)
Also: there are very, very few cases where std::vector<>::at is
appropriate. Are you sure you don't want [], with the bounds checking
you get in most modern implementations.
Instead of deriving from std::vector, in this case contain one (as a data member).
The problem with deriving is that it's then possible to treat a Histogram instance as just a std::vector, doing things that invalidate assumptions about the values of added data members.
In more technical jargon, with class derivation you have no guaranteed class invariant above the one provided by std::vector.
As a general rule of thumb, think of data member before class inheritance.
Sometimes inheritance is the thing, even inheritance from standard library container classes (e.g., std::stack is designed for inheritance), but not in this case.
About this: the size of the vector should always be 6.
You probably want to forbid some functionality to the user of the class. For example
vector::push_back
vector::pop_back
vector::insert
are functionalities that can change the size of the vector.
You can achive this by making such functions private members in the child class:
class aHistogram : public vector<int>
{
public:
aHistogram(){};
private:
vector<int>::push_back;
vector<int>::pop_back;
vector<int>::insert;
int numx, m, j;
};
Trying to learn something new every day I'd be interested if the following is good or bad design.
I'm implementing a class A that caches objects of itself in a static private member variable std::map<> cache. The user of A should only have access to pointers to elements in the map, because a full copy of A is expensive and not needed. A new A is only created if it is not yet available in the map, as construction of A needs some heavy lifting. Ok, here's some code:
class B;
class A {
public:
static A* get_instance(const B & b, int x) {
int hash = A::hash(b,x);
map<int, A>::iterator found = cache.find(hash);
if(found == cache.end())
found = cache.insert(make_pair(hash, A(b,x))).first;
return &(found->second);
}
static int hash(B & b, int x) {
// unique hash function for combination of b and x
}
// ...
private:
A(B & b, int x) : _b(b), _x(x) {
// do some heavy computation, store plenty of results
// in private members
}
static map<int, A> cache;
B _b;
int _x; // added, so A::hash() makes sense (instead of B::hash())
// ...
};
Is there anything that is wrong with the code above? Are there any pitfalls,
do I miss memory management problems or anything else?
Thank you for your feedback!
The implementation is intended to only allow you to create items via get_instance(). You should ideally make your copy-constructor and assignment operator private.
It would not be thread-safe. You can use the following instead:
const boost::once_flag BOOST_ONCE_INIT_CONST = BOOST_ONCE_INIT;
struct AControl
{
boost::once_flag onceFlag;
shared_ptr<A> aInst;
void create( const B&b, int x )
{
aInst.reset( new A(b, x) );
}
AControl() : onceFlag( BOOST_ONCE_INIT_CONST )
{
}
A& get( const B&b, int x )
{
boost::call_once( onceFlag, bind( &AOnceControl::create, this, b, x ) );
return *aInst;
}
};
Change the map to
map
Have a mutex and use it thus:
AControl * ctrl;
{
mutex::scoped_lock lock(mtx);
ctrl = &cache[hash];
}
return ctrl->get(b,x);
Ideally only get_instance() will be static in your class. Everything else is private implementation detail and goes into the compilation unit of your class, including AControl.
Note that you could do this a lot simpler by just locking through the entire process of looking up in the map and creating but then you are locking for longer whilst you do the long construction process. As it is this implements record-level locking once you have inserted the item. A later thread may find the item uninitialised but the boost::once logic will ensure it is created exactly once.
Any time you use globals (in this case the static map) you have to worry about concurrency issues if this is used across multiple threads. For example, if two threads were trying to get a particular instance at once, they could both create an object resulting in duplicates. Even worse, if they both tried to update the map at the same time it could get corrupted. You'd have to use mutexes to control access to the container.
If it's single-threaded only then there's no issue until someone decides it needs to be made multi-threaded in the future.
Also as a style note, while names starting with underscore+lower case letter are technically legal, avoid any symbols starting with underscores will avoid possibly accidentally breaking the rules and getting weird behavior.
I think these are 3 separate things that you mix together inside A:
the class A itself (what its intances are supposed to do).
poolling of instances for cache purposes
having such a static singlton pool for a certain type
I think they should be separate in the code, not all together inside A.
That means:
write your class A without any consideration of how it should be allocated.
write a generic module to perform pool cache of objects, along the lines of:
*
template< typename T > class PoolHashKey { ... };
template< typename T > class PoolCache
{
//data
private: std::map< .... > map_;
//methods
public: template< typename B > PoolKey< T > get_instance( B b );
public: void release_instance( PoolKey< T > );
// notice that these aren't static function members
};
create a singleton instance of PoolCache somewhere and use it:
*
PoolCache<A>& myAPool()
{
static PoolCache<A> s;
return s;
//you should use some safe singleton idiom.
}
int main()
{
B b;
PoolKey<A> const aKey( myAPool().get_instance( b );
A* const a( aKey.get() );
//...
myAPool().release_instance( aKey ); //not using it anymore
/*or else the destructor of PoolKey<A> should probably do some reference count and let the pool know this instace isn't needed anymore*/
}
Suppose you have a function, and you call it a lot of times, every time the function return a big object. I've optimized the problem using a functor that return void, and store the returning value in a public member:
#include <vector>
const int N = 100;
std::vector<double> fun(const std::vector<double> & v, const int n)
{
std::vector<double> output = v;
output[n] *= output[n];
return output;
}
class F
{
public:
F() : output(N) {};
std::vector<double> output;
void operator()(const std::vector<double> & v, const int n)
{
output = v;
output[n] *= n;
}
};
int main()
{
std::vector<double> start(N,10.);
std::vector<double> end(N);
double a;
// first solution
for (unsigned long int i = 0; i != 10000000; ++i)
a = fun(start, 2)[3];
// second solution
F f;
for (unsigned long int i = 0; i != 10000000; ++i)
{
f(start, 2);
a = f.output[3];
}
}
Yes, I can use inline or optimize in an other way this problem, but here I want to stress on this problem: with the functor I declare and construct the output variable output only one time, using the function I do that every time it is called. The second solution is two time faster than the first with g++ -O1 or g++ -O2. What do you think about it, is it an ugly optimization?
Edit:
to clarify my aim. I have to evaluate the function >10M times, but I need the output only few random times. It's important that the input is not changed, in fact I declared it as a const reference. In this example the input is always the same, but in real world the input change and it is function of the previous output of the function.
More common scenario is to create object with reserved large enough size outside the function and pass large object to the function by pointer or by reference. You could reuse this object on several calls to your function. Thus you could reduce continual memory allocation.
In both cases you are allocating new vector many many times.
What you should do is to pass both input and output objects to your class/function:
void fun(const std::vector<double> & in, const int n, std::vector<double> & out)
{
out[n] *= in[n];
}
this way you separate your logic from the algorithm. You'll have to create a new std::vector once and pass it to the function as many time as you want. Notice that there's unnecessary no copy/allocation made.
p.s. it's been awhile since I did c++. It may not compile right away.
It's not an ugly optimization. It's actually a fairly decent one.
I would, however, hide output and make an operator[] member to access its members. Why? Because you just might be able to perform a lazy evaluation optimization by moving all the math to that function, thus only doing that math when the client requests that value. Until the user asks for it, why do it if you don't need to?
Edit:
Just checked the standard. Behavior of the assignment operator is based on insert(). Notes for that function state that an allocation occurs if new size exceeds current capacity. Of course this does not seem to explicitly disallow an implementation from reallocating even if otherwise...I'm pretty sure you'll find none that do and I'm sure the standard says something about it somewhere else. Thus you've improved speed by removing allocation calls.
You should still hide the internal vector. You'll have more chance to change implementation if you use encapsulation. You could also return a reference (maybe const) to the vector from the function and retain the original syntax.
I played with this a bit, and came up with the code below. I keep thinking there's a better way to do this, but it's escaping me for now.
The key differences:
I'm allergic to public member variables, so I made output private, and put getters around it.
Having the operator return void isn't necessary for the optimization, so I have it return the value as a const reference so we can preserve return value semantics.
I took a stab at generalizing the approach into a templated base class, so you can then define derived classes for a particular return type, and not re-define the plumbing. This assumes the object you want to create takes a one-arg constructor, and the function you want to call takes in one additional argument. I think you'd have to define other templates if this varies.
Enjoy...
#include <vector>
template<typename T, typename ConstructArg, typename FuncArg>
class ReturnT
{
public:
ReturnT(ConstructArg arg): output(arg){}
virtual ~ReturnT() {}
const T& operator()(const T& in, FuncArg arg)
{
output = in;
this->doOp(arg);
return this->getOutput();
}
const T& getOutput() const {return output;}
protected:
T& getOutput() {return output;}
private:
virtual void doOp(FuncArg arg) = 0;
T output;
};
class F : public ReturnT<std::vector<double>, std::size_t, const int>
{
public:
F(std::size_t size) : ReturnT<std::vector<double>, std::size_t, const int>(size) {}
private:
virtual void doOp(const int n)
{
this->getOutput()[n] *= n;
}
};
int main()
{
const int N = 100;
std::vector<double> start(N,10.);
double a;
// second solution
F f(N);
for (unsigned long int i = 0; i != 10000000; ++i)
{
a = f(start, 2)[3];
}
}
It seems quite strange(I mean the need for optimization at all) - I think that a decent compiler should perform return value optimization in such cases. Maybe all you need is to enable it.