q[ =delete ] on a subclass virtual function #CSY

Not allowed, but there’s a static_assert solution explained in https://stackoverflow.com/questions/24609872/delete-virtual-function-from-a-derived-class

Goal is to disallow at compile time any invocation of this virtual function definition.

Advertisements

## CRTP usages #template Method

This write-up describes two usages of CRTP

I briefly read the excellent blog https://www.fluentcpp.com/2017/05/16/what-the-crtp-brings-to-code/. I feel CRTP is advanced for almost all the contexts I can think of. (In contrast,  I can see some “necessary” usages of SFINAE, such as the one in my little AddOrder.h)

https://stackoverflow.com/questions/262254/crtp-to-avoid-dynamic-polymorphism shows a simple [1] example of CRTP to replace virtual functions. How much efficiency improvement does it make? Questionable. I always say that if you want the lowest latency, then write selected modules in assembly language, and store it in hardware like FPGA.

[1] if there is anything simple in template meta-programming.

I have heard of several techniques to avoid virtual functions, but I believe the actual evidence (in terms of measured improvement in latency) is likely unconvincing or insignificant. Therefore, if CRTP is used to eliminate virtual function latency, then I am not sure how much value it adds.

There are other techniques to avoid “virtual”. I feel they are easier to understand than CRTP.

Q: for a virtual method v1(), the derived class is not yet written when the base class is compiled. Later, Only at run time can the “system” pick the right implementation of v1(). How about CRTP?
A: base class is not compiled ahead of the derived class. Each derived class includes the base class as a template in header.

Beside this “virtual-elimination” use case, CRTP has other applications (am still unfamiliar with), but if I’m asked in interviews I will only mention this one use case. One of the common “other usages” is TemplateMethod with compile time (not runtime) resolution, the 1st usage in the excellent blog . In the classic template method pattern, the “procedure” is published and finalized in the base class. Individual steps of the procedure are virtual methods, resolved at runtime. In the CRTP version, superclass methods call subclass methods, safely and cleanly. Superclass using subclass is a taboo in most contexts, but both traditional TemplateMethod and CRTP are notable exceptions.

The article didn’t clearly highlight a key point about this usage — The base class NumericalFunctions is general purpose, designed to be subclassed by anyone.  I could write a Temperature class to subclass NumericalFunctions too. This way, the code in NumericalFunctions is available for reuse.

template <typename Sub> struct NumericalFunctions { //templateMethod demo
    void square(){ //a reusable code to be "inherited" by any subclass
        Sub& underlying = static_cast<Sub&>(*this);
        // cast to Sub* is probably more common and I tested too.

        //Now we can Access subclass instance without using virtual function!
        underlying.setValue(underlying.getValue() * underlying.getValue());

        cout<<"from inside superclass square(), you can even access subclass field: "
            <<underlying._value<<endl;
    }
};
struct Sensitivity : public NumericalFunctions<Sensitivity> {
    double _value;
    double getValue() const{ return _value; }
    void setValue(double value){ _value = value; }
};
int main(){
  Sensitivity * inst = new Sensitivity;
  inst->setValue(17);
  inst->square();
  cout<<inst->getValue();
}

Key points to remember about the code sample:

  • base-class — is a template with a dummy type “Sub”
  • derived classes — have the form “class Sub1 public Base<Sub1>”
  • the static dispatch (non-virtual) function in Base always static_cast “this” to *Sub.

 

private dtor restricts allocation to heap only

My test proves that merely declaring the a stack instance or global instance is illegal because compiler generates a (illegal) call to the private dtor!

Friend can also call dtor!

class PrivDtor{
  ~PrivDtor(){
        cout<<"dtor\n";
  }
public:
  static void destroy(PrivDtor* p){p->~PrivDtor();}
  static void del(PrivDtor* p){delete p;}
};

//PrivDtor globalInstance;  //won't compile
int main(){
  //PrivDtor stackInstance; //won't compile

  PrivDtor * p = new PrivDtor;
  //PrivDtor::del(p); // works!
  PrivDtor::destroy(p);  //works!
}

#include <xtap/PluginConfig.h> trick

I have seen in many large systems:

The actual path to the header is …/shared/tp_xtap/include/PluginConfig.h, but develoeprs prefer an abbreviated include like #include <xtap/PluginConfig.h>.

#1) Here’s one simple implementation:

ls -l shared/tp_xtap/include/ # should show a symbolic link to be created automatically:

    xtap -> ./

Therefore, -I/full/path/to/shared/tp_xtap/include/ will resolve #include <xtap/PluginConfig.h>

#2) I guess a second-best solution is code generation. Checked-in source file has #include <xtap/PluginConfig.h> but the build system follows configured rewrite-rules, to convert it into #include <some/other/path>

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

memset: a practical usage #Gregory

  • memset is a low-level C function.
  • memset takes a void pointer.
  • Fast and simple way to zero out an array of struct, having primitive data members. No std::string please. No ptr please. Use sizeof to get the byte count.
  • Useful in low level wire coding
// illustrates packed and memset
#include <iostream>
using namespace std;

struct A{
  unsigned int i1; //4 bytes
  bool b; //1 byte
  char cstr[2];
  int* ptr; //8 bytes
} __attribute__((packed));
size_t const cnt = 3;
A arr[cnt];
int main(){
  cout<<sizeof(A)<<endl;
  size_t sz = sizeof(arr);
  cout<<sz<<endl;
  memset(arr, 0, sz);
  for(size_t i=0; i<cnt; ++i){
    A* tmp = &arr[i];
    cout<<"i1 = "<<tmp->i1<<"; b = "<<tmp->b<<" ; cstr[1] = "<<(int)tmp->cstr[1]<<" ptr = "<<tmp->ptr<<endl;
  }
}

file (de)serialization, for array of simple structures #Gregory

Not needed for IV..

// simple and fast (de)serialization to file given an array of structures

#include <fcntl.h>
#include <iostream>
using namespace std;
size_t const len=15;

struct A{
        int i1;
        char cstr[len];
        //string s4; //doesn't really work
        A(int i=999, string cs="default c-string", string s="default std::string"): i1(i){
                strncpy(cstr, cs.c_str(), len);
        }
};
size_t const  cnt=2, siz=cnt * sizeof(A);
A arr[cnt], ar2[cnt];

char fname[] = "/tmp/,.dat";
int main() {
        arr[0]=A(1,  "grin", "backbone");
        arr[1]=A(2,  "frown", "try/except/else");

        int fd = open(fname, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
        write(fd, arr, siz);
        close(fd);

        int fd2 = open(fname, O_RDONLY);
        read(fd2, ar2, siz);
        close(fd2);

        for (int idx = 0; idx < cnt; ++idx){
                A * tmp = ar2 + idx;
                cout<<tmp->i1<<" ; "<<tmp->cstr<<" ; "<<endl; //tmp->s4<<endl;
        }
}

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;
}

 

nested class having ptr to outer-class Object]java,c#,c++

Usually java is cleaner than c++ and c#. However, in this case I believe java is the Least clean.

Java “non-static nested class” feature is not “embraced” by Microsoft. All c# nested classes are static and can’t access non-static fields of the enclosing class.

C++ doesn’t support java style inner class either. See http://bigblog.tanbin.com/2009/03/nonstatic-nested-class-has-no-pointer.html

subverting – multiple inheritance #my take

!! With MI, the “this” pointer field is not always identical between the Base object and the Derived object.
** Remember a primitive technique of a home-made “class” is a C struct + a self-pointer field [2]. Similarly, In Python methods, “self” must be the first argument…

[2] I don’t think we should add a 32-bit field to each instance! I guess compiler can help make do without it.

!! In a Derived instance, there’s not always a single Base1 instance.
** Basic example — D extends C1 and C2, which both extend B.
** Even if C1 and C2 both virtually extend B, if C3 extends B without “virtual”, D instance still embeds 2 B instances.

!! Casting within inheritance hierarchy doesn’t always maintain the address held inside a Derived pointer or Base pointer. SI — always. ARM P 221 says “with MI, casting changes the value of a pointer”.

!! Each Derived instance uses more than one vtbl. If D inherits from B1 and B2, then that instance uses two vtbl’s. See ARM P230.

!! AOB (see other posts) assumes a 0 “delta” but in MI, delta is introduced because it’s not 0! ARM P222

— Below rules still holds,  in SI and MI —
dtor sequence is the exact reverse of ctor sequence which is BCDC (see other posts)

c++ nested class experiment

#include
class Outer{
   int m_o;
   public:
   class Inner   {
      public:
        int m_i;
        Inner(){m_i=999;}
        Inner(Outer & m_outer, int x){
           m_outer.m_o = x; //against c++98
        }
   };
   Outer(int y)   {
       cout <m_inner.m_i<<" <—- this field is no-arg constructed.n";
       m_inner.m_i = y;
   }
   void Display()   {
       using namespace std;
       cout << m_o << endl
            << m_inner.m_i << endl;
   }
   Inner m_inner;
};
int main(){
   Outer    objOut(10); //inner == 10
   Outer::Inner objIn(objOut, 5); // objIn discarded, but objOut modified to 5
   objOut.Display();
   cin.get();
}

prevent heap instantiation4my class #part2

[[C++FAQ]] and [[More Eff C++]] both cover related topics.

I feel it’s very useful to have classes that can only be instantiated on stack, because stack-variables are automatically reclaimed.

With these classes, no double-delete, no dangling pointer, and most importantly, no memory leak. Remember memory leak is the most hidden — hardest to identify.

prevent heap instantiation4my class#Part 1

(Much of this write-up is based on http://www.cprogramming.com/tutorial/operator_new.html) It’s useful if we can restrict a special class’s instantiation to the stack only, and disallow heap allocation. Overload op-new for your class, and make it throw exception unconditionally? Alternatively, can we declare it but leave it unimplemented like —

class Myclass {
public:
void* operator new(size_t);
void operator delete(void*);
};

Both of them are by default static members. Overloading can be used for many purposes. For example, we may need to alter the exception thrown in case of failure–std::bad_alloc–and throw something else:

The relationship between Operator New and the New Keyword

Don’t be confused by the fact that there is both a new keyword and an operator new. When you write:

MyClass *x = new MyClass;

there are actually two things that happen–memory allocation and object construction; the new keyword is responsible for both. One step in the process is to call operator new in order to allocate memory; the other step is to actually invoke the constructor. Operator new lets you change the memory allocation method, but does not have any responsibility for calling the constructor. That’s the job of the new keyword.

It is possible to invoke the constructor without calling operator new. That’s the job of placement new

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

real-world OMS c++data structure for large collection of orders

class OrderMap{
struct data_holder {/*fields only. no methods*/};
unordered_map<int, shared_ptr<data_holder> > orders; // keyed by orderID
… //methods to access the orders
};

Each data_holder is instantiated on heap, and the new pointer goes into a shared_ptr. No need to worry about memory.

Do you see ANY drawback, from ANY angle?

a function as a friend to 2 classes

“I name my friends”. I’m a class with private fields/methods. I can name another class to be a “friend-class”, so its *instance* can access private members of my *instance*.

Now friend-function — I can also name a function as my friend. The function is identified by the full prototype (including const, return type …). Therefore, when i name the friend function, the syntax looks …..

The access controller treats each function [1] as an “thingy”, a special thingy in a running process, with its own identity (and address).

Now you can understand that a function can be friend to 2 classes.

[1] non-member, non-friend functions included, and also overloaded operators

See also http://newdata.box.sk/bx/c/htm/ch15.htm for transfer and inheritance resitrictions