I completely failed this 2011 IV question from MIAX options exchange:
Q: outline a ref-counted copy-on-write string class, showing all the function declarations
A: here’s my 2017 answer
char * arr;
unsigned int refCount; // size_t is more conventional
~Str(); //decrement and if needed, delete the payload
//Str(); //empty ctor is useless since we can't really modify this instance, due to copy-on-write
Str(Str const &); // similar to shared_ptr
Str & Operator=(Str const & other) const; // will return a reference to another instance constructed on heap (never on stack!)
Str & replace_with(char const * arr, size_t const len) const; //ditto
// optional utilities
char const * c_str() const; // <-- Hey mine is very similar to std::string
Str(char const * arr, size_t const len); // <-- Hey mine looks similar to std::string
Str(std::str const &);
friend ostream & operator<<(ostream &, Str const &); // <-- Hey I got this right 100%
There are various claims on what specific big4 requirements a vector would impose on the payload objects.
Q: can no-arg ctor be private?
%%A: I doubt it. I remember [[essential c++]] or another well known author said when you create a vector or array of N instances, those instance are default-constructed.
Q: Can copy ctor be deleted or private?
AA: No. Reallocation requires copy ctor
Q: can dtor be private?
%%A: No. At reallocation time, old instances must be destructed.
[[optimized c++]] introduced the unofficial, unenforceable "framework" of value object vs entity object. Vector obviously hold value objects, so by right they should be copyable, with no shared ownership.
In 2011 some interviewer asked me how to implement assignment using copy ctor for my class.
http://www.geeksforgeeks.org/copy-swap-idiom-c/ shows one technique. Not sure if it’s best practice.
In practice, your custom class should have either no ctor or at least a no-arg ctor. This is practical advice in [[c++ primer]]
The array-new operator, vector and other containers all require that
– either your class has no ctor
– or you provide a no-arg.
In other words, no-arg is the first ctor to be provided.
See more details in my post https://bintanvictor.wordpress.com/2013/08/12/c-no-arg-ctor-call-without-new-confusing/. Is there anything new
here? No, just another summary.
On heap (“new”) or with ctor args, things are more clear-cut and we make fewer mistakes. My confusions are the no-arg ctor calls on
Animal a1; //ctor. Standard idiom but I would try to use the alternative form below.
Animal a2 = Animal(); // ctor – temp obj. This form is possibly less efficient, but this form is flexible —
Animal a3 = Animal(someArt)
// Above syntax may or may not create additional temp objects, in c++03 or c++11.
Animal aX(); // NOT ctor
throw Animal(); //ctor – temp obj
function6(Animal() );//ctor – temp obj
Rule of thumb — All the Animal() expressions create a temp.
Neither the allocation or the ctor step is universal and guaranteed to happen.
new int; // This won't invoke any ctor since “int” is not a class/struct and doesn't have a ctor.
More importantly, if allocation fails then no “raw memory” is there to initialize.
It's possible to bypass the allocation, if you use placement-new