array as field #implementation pattern

array field is less common in java/c# than in c++ and include vector, hashtable, deque.

As an alternative, please consider replacing the array with a vector. This would use heap memory but total memory usage is probably similar.

  • benefit — lower risk of seg fault due to index out of range
  • benefit — growable, though in many cases this is unneeded
  • benefit — different instances can different sizes, and the size is accessible at run time.
  • benefit — compared to a heap array as a field, vector offers RAII safety
Advertisements

STL+smart_pointer for SQL DTO

Are there any best practice online?

Q1: Say I have a small db table of 10 columns x 100 rows. Keys are
non-unique. To cache it we want to use STL containers. What container?
%%A: multimap or list. unordered_multimap? I may start with a vector, for simplicity. Note if 2 duplicate rows aren’t 100% identical, then multimap will lose data

Q1a: search?
%A: for a map, just lookup using this->find(). For list, iterate using generic find()

Q1c: what if I have a list of keys to search?
%%A: is there an “set_intersect()” algorithm? If none, then I would write my nested iteration. Loop through the target keys, and find() on each.
A: for_each()?

Q1e: how do you hold the 10 col?
%%A: each object in container will have 10 fields. They could be 10 custom data classes or strings, ints, floats. Probably 10 smart pointers for maximum flexibility.

Q1h: what if I have other tables to cache too?
%%A: parametrize the CacheService class. CacheService class will be a wrapper of the vector. There will be other fields beside the vector.

Q1m: how about the data class? Say you have a position table and account table to cache
%%A: either inheritance or template.

pointer/itr as field: a top3 implementation pattern

common interview question.

This mega-pattern is present in 90% of java and c# classes, and also very common in c++. Important data structure classes  relying on pointer fields include vectors, strings, hashtables and most STL or boost containers.

Three common choices for a pointer member variable:

  • Raw pointer — default choice
  • shared_ptr — often a superior choice
  • char pointer, usually a c-str

In each case, we worry about

  • construction of this field
  • freeing heap memory
  • RAII
  • what if the pointee is not on heap?
  • copy control of this field
  • ownership of the pointer
  • when to return raw ptr and when to return a smart ptr

shared_ptr field offers exception safety, automatic delete, default synthesized dtor, copier, op=

 

2 simple yet concurrent singleton implementations ] c++

Both designs are thread-safe.

  1. First design is the static factory method + a static data member initialization.
  2. Second design uses a local static object, based on [[eff C++]] P 222.
template<class T>
class StaticFieldSingleton {
private:
 static StaticFieldSingleton<T> instance_; //declaration of static field
 StaticFieldSingleton() {
  cout << "StaticFieldSingleton() ctor\n";
 }
 StaticFieldSingleton(StaticFieldSingleton<T> const &);
 StaticFieldSingleton<T>& operator=(StaticFieldSingleton<T> const &);
public:
 static StaticFieldSingleton<T>& getInstance() {
  return instance_;
 }
}; 
//separate definition required on any static field
template<class T> StaticFieldSingleton<t> StaticFieldSingleton<t>
::instance_; //<---def of static field: required complexity

///////////// 2nd design uses a static local object
class SimpleSingleton {
 SimpleSingleton() {
  cout << "SimpleSingleton()\n";
 }
 SimpleSingleton(SimpleSingleton const &);
 SimpleSingleton& operator=(SimpleSingleton const &);
public:
 static SimpleSingleton& get_instance() {
  static SimpleSingleton instance;//<----- cleaner syntax
  return instance;
 }
};
int main() {
 StaticFieldSingleton<float>::getInstance();

 SimpleSingleton& ins1 = SimpleSingleton::get_instance();
 SimpleSingleton& ins2 = SimpleSingleton::get_instance();
 cout << &ins1 << endl;
 cout << &ins2 << endl;
}

 

static object initialization order #lazy singletons

Java’s lazy singleton has a close relative among C++ idioms, comparable in popularity and implementation.

Basically, local statics are initialized upon first use, exactly. Other static Objects are initialized “sometime” before main() starts. See the Item on c vs c++ in [[More eff c++]] and P222 [[EffC++]].

In real life, this’s hard to control — a known problem but with standard solutions — something like a lazy singleton. See P 170 C++FAQ. Also addressed in [[EffC++]] P221.

c++ creational patterns – return pointers always

Many creation patterns need to return pointers.

Must use pbref not pbclone, so the choice is between pointer vs reference. I feel pointer is more flexible than reference. If creation fails, we can return NULL.

eg: virtual ctor, esp. clone()
eg: factory http://login2win.blogspot.com/2008/05/c-factory-pattern.html, [[ModernC++Design]]
eg: builder http://en.wikibooks.org/wiki/C++_Programming/Code/Design_Patterns/Creational_Patterns

pimpl -> bridge pattern

My pimco interviewer (Burak?) pointed out, again, the link between pimpl and bridge pattern. Perhaps he read [[effC++]]

See other posts about pimpl.

Based on whatever little i know about c++ design patterns, i feel bridge is arguably the most powerful, colorful pattern. Here’s one variation of the pattern, featuring bridge-over-2-trees. See [[head first design patterns]] and this detailed yet simple sample code

First you need to thoroughly master the pimpl idiom. Realize the pimp classes provide a service to a client.
-> To grasp the bridge pattern, remember the client is unimportant. It’s outside our picture.
-> Next, looking at the service side of the client-service divide. Realize we have refactored a single service class into an empty public facade[1] + a private impl (therefore PIMPL) class.
-> Next realize both classes can be abstract and subclassed.
-> We end up with 2 trees i.e. 2 class hierarchies. P292Duffy
Note the field in the empty public facade should be a pointer for maximum polymorphism and easy-copy
-> We see a link between the 2 trees since the facade HasA pointer to the pimpl class.
-> That link is the bridge!

[1] imprecisely

For More flexibility, we can use factory to manufacture subclasses. Factory must return pointers to avoid slicing.

pimpl, phrasebook

pointer – the private implementation instance is held by (smart) pointer, not by reference or by value
** P76 [[c++codingStandards]] suggests boost shared_ptr

big3 – you often need to avoid the synthesized dtor, copier and op=. See P…. [[c++codingStandard]]

FCD – see other posts

encapsulate – the “private” class is free to evolve
** wrapper class vs a private class. The public methods in the wrapper class simplify delegates to the private class.[[c++succinctly]] has a complete Pimpl example showing such “delegations”

## factory functions used with STL containers

If we use “factory” to refer to any function that can create a new object, then here are some of the factory functions (including cvctor) covered in my blog or my books.

– back_inserter — always used with something_copy() functions like replace_if/replace_copy_if, count_if, remove_if/remove_copy_if … See blog
– bind2nd — used in something_if() functions like copy, remove_copy, replace_copy … See blog
– customized binary_function like “myLess”. see blog on functor-object