non-virtual dtor: some random scenarios

Background — How important are these scenarios? First off, tech quizzes are extremely important since you are judged just over a few questions. Second, these scenarios pop up by accidents, rather than be design, all the time in real projects. You better learn to deal with a drunken driver while on the road.

Better test these:

Q: what if Base and Derived dtor both non-virtual and an autoVar is destroyed?
%%A: see post on DCBC.

Q: What if Base dtor is not virtual but Derived is virtual, and a Derived auto variable is destroyed on the stack?
%%A: For an autoVariable that’s not deleted via a ptr, Derived ctor (virtual or not) runs, followed by Base dtor. Same DCBC

Note the well-known __undefinedBehavior__ affects delete only, not stack variables or static variables.

Note virtual keyword affects pointer variable. Non-ref variables aren’t affected.

ref-counted copy-on-write string #MIAX exchange IV

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

class Str{
	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% 

big4 of a payload object in a std::vector

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.

c++ ctor calls(confusing), another summary

See more details in my post 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
the stack.

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.

new-expression alloates AND invokes ctor…most of the time

Neither the allocation or the ctor step is universal and guaranteed to happen.

1) ctor

If allocation fails then no “raw memory” is there to initialize.

new int; // This won’t invoke any ctor since “int” is not a class/struct and doesn’t have a ctor.

2) allocation

It’s possible to bypass the allocation, if you use placement-new

op-new : no DCBC rule

B’s op-new is bypassed by D’s op-new [1]
B’s ctor is always used (never bypassed) by D’s ctor.

This is a interesting difference.

Similarly, an umbrella class’s op-new [1] would not call a member object’s op-new. See [[more effC++]]

These issues are real concerns if you want to use op-new to prohibit heap instantiation of your class.


[1] provided these two classes each define an op-new()

By the way, op-new is a static member operator, but is still inherited.