Custom Weak/Strong Reference Pointers - c++

I am creating my own implementation of a weak/strong reference pointer relationship and I am confused to the configuration. When I have a class that contains the strong reference, and I want to set the strong pointer to another class that has a weak reference, should I be passing in the pointer of a weak_ref pointer?
If someone could please take a look at this code and let me know I will appriciate it, also if you notice any other issues please let me know. I put the three files into codepad files so this page does not become cumbersome.
WeakReference.h : http://codepad.org/nNtRk4vO
StrongReference.h : http://codepad.org/MGi0fZ4J
Please do not turn this into a "use boost, use std, use tr1" argument, I am looking for help on this code, not using something else.

The implementations that I have seen, and that I have worked on, that use the concepts of strong and weak reference, all use two counts. Sometimes one count is the number of weak references and the other is the number of strong. Other times one of the counts represents the sum of strong + weak references. Sometimes there are other schemes. But I have not yet seen an implementation with only one count as yours seems to have.
Perhaps it would help if you wrote a specification for exactly what the behavior for strong_ref and weak_ref are supposed to be. I find that the act of writing a specification can actually aid in the debugging of the implementation. It forces you to think about inputs, outputs, corner cases, invalid cases, etc.

Related

Definition of object and instantiation

According to What is a Class and Object in C++?
A Class is like a blueprint, an object is like a house built from that
blueprint.
You can have many houses with the same layout/floorplan (read class),
but each is it's own instance (read object). Each has it's own owner,
furniture, etc.
Note that there are also objects whose blueprint is not a class (e.g.
integers).
In summary, there are different types of object (e.g. int, float, etc.). You can create user-defined types, called 'classes'.
In C++, the term object is used for instances of any type, including classes and fundamental types.
However, according to http://www.cplusplus.com/doc/tutorial/classes/
An object is an instantiation of a class. In terms of variables, a
class would be the type, and an object would be the variable.
Isn't that statement inaccurate? An object could be an instantiation of a class, but it could also be an instance of a fundamental type.
Then what is instantiation?
Is creating an instance of a fundamental type (ex. int x = 3;) considered "instantiation"? Since it is technically creating an instance of a type.
An object is an instance of a type.
Moving on to your questions:
Isn't that statement (the cppreference one) inaccurate ? An object could be an instantiation
of a class, but it could also be an instance of a fundamental type.
You are correct.
Also, wouldn't creating an instance of a fundamental type (ex. int x =
3;) be considered "instantiation"? Since it is technically creating an
instance of a type.
Again, correct.
Personal advice: stop worrying too much about the exact definitions and spend your energy more on "learning by writing code"
how is instantiation defined?
Ok, since you are insisting, here is me kindly pushing back:
All the definitions you will find online or in books are not authoritative. The only authority on these things is the C++ standard: here take a peek: N4713. As you can see, the standard is overly technical and difficult to parse and understand. And it is this way because it is in no way meant to be used for learning, it is meant to thoroughly and unambiguously define the syntax and semantics of the language. It's the document the compiler implementators turn to when writing the compiler that you use to convert that sweet C++ source code into machine code.
Since the standard is not a way to learn C++, everybody came up with their own definitions and terminology meant to more easily convey sometimes much more complex matters. In doing so, sometimes the definitions you see are incomplete, or slightly wrong, or don't apply in weird corner cases. You will find the same terms are used slightly different by different authors. Is this a bad thing? Maybe, but not by much. When learning it is important to have simple concepts and tools at your disposal so that you can take things one step at a time. Losing that "rigorous thoroughness" is a small price to pay imho, but I see how this can be confusing for people who take every word in learning materials very seriously.
Coming back to your question: in the standard, as far as I can see the termn "instantiation" is not used in this sense, it's used for "template instantiation" which is a different thing.
But that's ok, we don't need the standard to understand a simple concept. For your context an instantiation is the creation of an object. It's a very simple concept, don't overthink it.
The C++ standard uses "instantiation" for a different purpose, but you still can understand the concept. Name it something else if you will.

forcing a function to be pure

In C++ it is possible to declare that a function is const, which means, as far as I understand, that the compiler ensures the function does not modify the object. Is there something analogous in C++ where I can require that a function is pure? If not in C++, is there a language where one can make this requirement?
If this is not possible, why is it possible to require functions to be const but not require them to be pure? What makes these requirements different?
For clarity, by pure I want there to be no side effects and no use of variables other than those passed into the function. As a result there should be no file reading or system calls etc.
Here is a clearer definition of side effects:
No modification to files on the computer that the program is run on and no modification to variables with scope outside the function. No information is used to compute the function other than variables passed into it. Running the function should return the same thing every time it is run.
NOTE: I did some more research and encountered pure script
(Thanks for jarod42's comment)
Based on a quick read of the wikipedia article I am under the impression you can require functions be pure in pure script, however I am not completely sure.
Short answer: No. There is no equivalent keyword called pure that constrains a function like const does.
However, if you have a specific global variable you'd like to remain untouched, you do have the option of static type myVar. This will require that only functions in that file will be able to use it, and nothing outside of that file. That means any function outside that file will be constrained to leave it alone.
As to "side effects", I will break each of them down so you know what options you have:
No modification to files on the computer that the program is run on.
You can't constrain a function to do this that I'm aware. C++ just doesn't offer a way to constrain a function like this. You can, however, design a function to not modify any files, if you like.
No modification to variables with scope outside the function.
Globals are the only variables you can modify outside a function's scope that I'm aware of, besides anything passed by pointer or reference as a parameter. Globals have the option of being constant or static, which will keep you from modifying them, but, beyond that, there's really nothing you can do that I'm aware.
No information is used to compute the function other than variables passed into it.
Again, you can't constrain it to do so that I'm aware. However, you can design the function to work like this if you want.
Running the function should return the same thing every time it is run.
I'm not sure I understand why you want to constrain a function like this, but no. Not that I'm aware. Again, you can design it like this if you like, though.
As to why C++ doesn't offer an option like this? I'm guessing reusability. It appears that you have a specific list of things you don't want your function to do. However, the likelihood that a lot of other C++ users as a whole will need this particular set of constraints often is very small. Maybe they need one or two at a time, but not all at once. It doesn't seem like it would be worth the trouble to add it.
The same, however, cannot be said about const. const is used all the time, especially in parameter lists. This is to keep data from getting modified if it's passed by reference, or something. Thus, the compiler needs to know what functions modify the object. It uses const in the function declaration to keep track of this. Otherwise, it would have no way of knowing. However, with using const, it's quite simple. It can just constrain the object to only use functions that guarantee that it remains constant, or uses the const keyword in the declaration if the function.
Thus, const get's a lot of reuse.
Currently, C++ does not have a mechanism to ensure that a function has "no side effects and no use of variables other than those passed into the function." You can only force yourself to write pure functions, as mentioned by Jack Bashford. The compiler can't check this for you.
There is a proposal (N3744 Proposing [[pure]]). Here you can see that GCC and Clang already support __attribute__((pure)). Maybe it will be standardized in some form in the future revisions of C++.
In C++ it is possible to declare that a function is const, which means, as far as I understand, that the compiler ensures the function does not modify the object.
Not quite. The compiler will allow the object to be modified by (potentially ill-advised) use of const_cast. So the compiler only ensures that the function does not accidentally modify the object.
What makes these requirements [constant and pure] different?
They are different because one affects correct functionality while the other does not.
Suppose C is a container and you are iterating over its contents. At some point within the loop, perhaps you need to call a function that takes C as a parameter. If that function were to clear() the container, your loop will likely crash. Sure, you could build a loop that can handle that, but the point is that there are times when a caller needs assurance that the rug will not be pulled out from under it. Hence the ability to mark things const. If you pass C as a constant reference to a function, that function is promising to not modify C. This promise provides the needed assurance (even though, as I mentioned above, the promise can be broken).
I am not aware of a case where use of a non-pure function could similarly cause a program to crash. If there is no use for something, why complicate the language with it? If you can come up with a good use-case, maybe it is something to consider for a future revision of the language.
(Knowing that a function is pure could help a compiler optimize code. As far as I know, it's been left up to each compiler to define how to flag that, as it does not affect functionality.)

Pertinence of void pointers

Looking through a colleague's code, I see that some of its handles are stored as void pointers.
// Class header
void* hSomeSdk;
// Class implementation
hSomeSdk = new SomeSDK(...);
((SomeSDK*)hSomeSdk)->DoSomeWork();
Now I know that sometimes handles are void pointers because it may be unknown before runtime what will be the actual type of the handle. Or that it can help when we need to share the pointer without revealing its actual structure. But this does not seem to be the case in my situation: it will always be SomeSDK and it is not shared outside the class where it is created. Also the author of this code is gone from the company.
Are there other reasons why it would make sense to have it be a void pointer?
Since this is a member variable, I'm gonna go out on a limb and say your colleague wanted to minimize dependencies. Including the header for SomeSDK is probably undesirable just to define a pointer. The colleague may have had one of two reasons as far as I can see from the code you show:
They just didn't know they can add a forward declarations like class SomeSDK; to allow defining pointers. Some programmers just aren't aware of it.
They couldn't forward declare it. If SomeSDK is not a class, but a type alias (aka typedef), then it's not possible to forward declare it exactly. One can only declare the class it aliases, but that in turn may be an implementation detail that's hard to keep track of. Even the standard library has a similar problem, that is why it provides iosfwd to make forward declaring standard stream types easier.
If the code is peppered with casts of this handle, then the design should have been reworked ages ago. Otherwise, if it's in one place (or a few at most) only, I can see why the people maintaining it could live with it peacefully.
Nope.
If I had to guess, the ex-colleague was unfamiliar with forward declarations and thus didn't know they could still do SomeSDK* in the header without including the entire SomeSDK definition.
Given the constraints you've mentioned, the only thing this pattern achieves is to eliminate some type safety, make the code harder to read/maintain, and generate a Stack Overflow question.
void* were popular and needed back in C. They are convenient in the sense that they can be easily cast to anything. If you need to cast from double* to char*, you have to make a mid cast to void*.
The problem with void* is that they are too flexible: they do not convey intentions of the writer, making them very unsafe especially in big projects.
In Object Oriented Design it is popular to create abstract interface classes (all members are virtual and not implemented) and make pointers to such classes and then instantiate various possible implementation depending on the usage.
However, nowadays, it is more recommended to work with templates (main advantage of C++ over other languages), as those are much faster and enable more compile-time optimization than OOD allowed. Unfortunately, working with templates is still a huge hassle - they have more complicated syntax and it is difficult to convey intentions of the writer to users about restrictions and demands of the template parameters (Concepts TS that solves this problem decently will be available in C++20 - currently there is only SFINAE, a horrible temporary solution from 20 years ago; while Reflection TS, that will greatly enhance generic programming in C++, is unlikely to be available even in C++23).

What are the disadvantages of dynamic_cast in C++?

Despite the fact that dynamic_cast returns a 0 if the pointer that is being handled is of an incompatible type, why would you avoid using dynamic_cast?
It takes non-zero runtime. That is about it. C-casts and their c++ counter parts like: reinterpret or static are 0-overhead because they are performed during compilation.
Well for some, important part might be that they do need RTTI, which also introduces some overhead, for example to the code size, because compiler has to include type information into binary, which is not normally done. One should take note that this might be non-standard option in the compilers.
Also relevant note from wiki: "In the original C++ design, Bjarne Stroustrup did not include run-time type information, because he thought this mechanism was frequently misused."
EDIT: Following on the quote and the comments. I am not sure if this is really a drawback, I would like to point out, that when you use it, you should think if you really do need it.
Some just dislike it, some do misuse it.
Run-time overhead:
More memory is needed to store RTTI (see link).
Types must be checked at runtime.
Design Issues:
Types involved must be polymorphic.
Is often a sign of something else wrong in your code; why do you need to check?

Which is the best among GetCountOfObjects, GetNumberOfObjects, and GetObjectCount?

I am a C++ programmer from a non-English country.I am always confused about how to choose one of the following function names:
GetCountOfObjects
GetNumberOfObjects
GetObjectCount
Who can tell me what the subtle differences are between them?
I'm also a programmer from non-English country, but I think the best way to choose the name is
use the name that is the most clear
use the shortest name enough to understand easily
Also, english language suppose that it's better to swap the order than use 'Of'.
So, IMHO the best variant is 'GetObjectCount' here, of course if it returns the quantity of object.
GetNumberOfObjects probably sounds closest to natural English. GetCountOfObjects sounds slightly awkward. Other than that, there is almost no difference.
My personal style would probably be to use GetNumberOfObjects for a method that just returns a known number, but CountObjects for a method that actually performs the counting.
EDIT: The reason for this difference, at least to me, is that the word 'number' is more commonly used as a noun while 'count' is more commonly used as a verb.
Really, this is a style choice. Use whatever you choose consistently and it will be fine.
Use whatever you want, but use it consistently.
I would go for the shortest simplest: size() if it makes sense. That is, if you are trying to add a member function to a class that somehow resembles a container, using the same names that are used in existing libraries for the same concepts will make code simpler to read.
Even if that does not make sense, while in Java getters and setters are common, in many C++ libraries the same function names will drop the get part and provide a shorter name: GetNumberOfObjects => NumberOfObjects, GetObjectCount => ObjectCount... If you want to make your object different from containers (and thus you explicitly want to avoid size()) I would probably go for objectCount or numObjects. While numObjects is not proper english it is easy to read and interpret and it is short.
use whichever u feel comfortable wid but be consistent wid it.avoid very long names as u can err.also u can use sum kind of distinction in d names 2 help u figure out type of variable or whether it is static,local or public or private