overloading dereference operator - overloading

I am new to C++ and i have a question on overloading dereference operator. I am building a in memory object store which is to be used by the applications. The data store is mapped in to the applications memory space and applications can directly read/modify the object using dereference operator . I plan to provide an interface described below
DsObject *obj = get_ds_object_ref ("Junk"); // get reference to the object
int i = obj->value; // obj is read locked and the value is copied to i variable
obj->value = i; // obj is write locked and i is copied to the field "value"
In the operator overload function is there a way to know whether the object is being read or written ? suggestions are welcome.

I suggest you to use get/set functions, they provide required operation type: read or write.

No, I don't think so. It is not possible (AFAIK) to determine how obj->value is being used.
Perhaps you will need something like this:
DsObject *obj = get_ds_object_ref ("Junk");
int i = GetValue(obj);
SetValue(obj,i);
I'm sorry that there is not much more you can do.

To achive a lock to the object you need an additional proxy object. Let the derefence (o any other) operator return the proxy that provides a cast opeator to get the intenden type. The lifetime of the proxy may be used to define a lock.

Related

Is this the right way to return a struct in a parameter?

I made the following method in a C++/CLI project:
void GetSessionData(CDROM_TOC_SESSION_DATA& data)
{
auto state = CDROM_TOC_SESSION_DATA{};
// ...
data = state;
}
Then I use it like this in another method:
CDROM_TOC_SESSION_DATA data;
GetSessionData(data);
// do something with data
It does work, returned data is not garbage, however there's something I don't understand.
Question:
C++ is supposed to clean up state when it has exitted its scope, so data is a copy of state, correct ?
And in what exactly it is different from the following you see on many examples:
CDROM_TOC_SESSION_DATA data;
GetSessionData(&data); // signature should be GetSession(CDROM_TOC_SESSION_DATA *data)
Which one makes more sense to use or is the right way ?
Reference:
CDROM_TOC_SESSION_DATA
Using a reference vs a pointer for an out parameter is really more of a matter of style. Both function equally well, but some people feel that the explicit & when calling a function makes it more clear that the function may modify the parameter it was passed.
i.e.
doAThing(someObject);
// It's not clear that doAThing accepts a reference and
// therefore may modify someObject
vs
doAThing(&someObject);
// It's clear that doAThing accepts a pointer and it's
// therefore possible for it to modify someOjbect
Note that 99% of the time the correct way to return a class/struct type is to just return it. i.e.:
MyType getObject()
{
MyType object{};
// ...
return object;
}
Called as
auto obj = getObject();
In the specific case of CDROM_TOC_SESSION_DATA it likely makes sense to use an out parameter, since the class contains a flexible array member. That means that the parameter is almost certainly a reference/pointer to the beginning of some memory buffer that's larger than sizeof(CDROM_TOC_SESSION_DATA), and so must be handled in a somewhat peculiar way.
C++ is supposed to clean up state when it has exitted its scope, so
data is a copy of state, correct ?
In the first example, the statement
data = state
presumably copies the value of state into local variable data, which is a reference to the same object that is identified by data in the caller's scope (because those are the chosen names -- they don't have to match). I say "presumably" because in principle, an overridden assignment operator could do something else entirely. In any library you would actually want to use, you can assume that the assignment operator does something sensible, but it may be important to know the details, so you should check.
The lifetimes of local variables data and state end when the method exits. They will be cleaned up at that point, and no attempt may be made to access them thereafter. None of that affects the caller's data object.
And in what exactly it is different from the following you see on many
examples:
CDROM_TOC_SESSION_DATA data;
GetSessionData(&data);
Not much. Here the caller passes a pointer instead of a reference. GetSessionData must be declared appropriately for that, and its implementation must explicitly dereference the pointer to access the caller's data object, but the general idea is the same for most intents and purposes. Pointer and reference are similar mechanisms for indirect access.
Which one makes more sense to use or is the right way ?
It depends. Passing a reference is generally a bit more idiomatic in C++, and it has the advantage that the method does not have to worry about receiving a null or invalid pointer. On the other hand, passing a pointer is necessary if the function has C linkage, or if you need to accommodate the possibility of receiving a null pointer.

C++ controlling memory access and pointer dereferencing

I am writing an API in C++ where I want to restrict what a programmer can do with pointers to objects the API creates.
For example,
// API
class object {
// details unimportant
};
// Programmer's code
object o; // OK
object *op = &o; // OK
long *lp = (long *)op; // No
object o2 = op[100]; // No
I understand that some of this is probably difficult or impossible given C++'s type system. Are there ways to enforce this kind of type usage pattern? Are there ways to restrict the available operations on a given pointer type? Would something like overloading object's operator& work?
class object {
object_pointer operator&();
};
There is no way in C++ to prevent C-style casting of pointers. Any (non-function) pointer may be C-style cast to any other pointer type.
And given a pointer, there is no way to tell the compiler "This is definitely not an array." So you can't prevent op[100] either.
What you could do is hide all the members of the class itself, e.g. using the Pimpl idiom or C-style opaque structures/classes. But this won't help you in terms of restricting users' abilities to obtain pointers to your instances and cast them.
C++ is a language for consenting adults. If you don't consent, use another language.

Monitoring Memory Allocation in The C++

What is the best way to monitor memory allocation/de_allocation in the source code.
I have a C++ program which allocates large amount of memory dynamically and I want to keep track of that which object from which class is taking and freeing memory.
What I want in the output of my program is:
Creating Object from ClassA, Memory Usage ...
Creating Object from ClassB, Memory Usage ...
...
Freeing Object from ClassA, Memory Freed ...
What I'm doing now is simply overloading global new operator, but I heard it is not very safe.
Moreover, I need a way that dose't require to change all of my classes (i.e. using a base class and all classes have a string variable ClassName).
------------------------------------- Edit --------------------------------------
1- I don't want to use external tools and need to do it in the code.
2- If I overload global new operator, how I can access the Name of class or other members?
Take a look at MS tool called application verifier also take a look VS2010 profiler.
I hate this tool for tracking down memory leaks, but for monitoring allocs/dellocs it should do what you want: UMDH.
In highly depends on whether you want to do it in development only or in production as well and what your performance requirements are. For development on Linux you would normally start from Valgrind's Massif, if you are looking at a more custom solution and/or production mode you may look at combining malloc/calloc/realloc overriding code (my example here) with libunwind.
2- If I overload global new operator, how I can access the Name of class or other members?
You can't. You have to understand that the new and delete operators are not straight function calls. In effect, a syntax like MyClass* p = new MyClass(); is equivalent to:
MyClass* p = (MyClass*) malloc(sizeof(MyClass)); // A) allocate the memory.
new(p) MyClass(); // B) call constructor (via placement-new syntax (to illustrate)).
While a delete p; is equivalent to:
p->~MyClass(); // C) call destructor.
free(p); // D) free the memory.
When you overload the new-delete operators, all that the compiler actually permits you to overload are the steps A) and D), respectively. In other words, when you reach the body of the custom new operator, the object is not yet created, and thus, you can't access or print any information about it (class, name, etc.), except its address in memory, which you could print in your overloaded new. Similarly, by the time you reach your custom delete operator, the object has been destroyed and any attempts to use any information that might still be dangling in that memory is undefined behavior, especially if you want to use a virtual function or a string value.
Really, the best you can do with this approach is to print the pointers created in the new operator and print the pointers deleted by the delete operator.
And, as others have mentioned, you must be wary of infinite recursions when doing operations within the new-delete operators. For example, a simple line like:
std::cout << "Created pointer: " << reinterpret_cast<std::size_t>(p) << std::endl;
will almost certainly cause many calls to new and delete (creating temporary strings, extending buffers, etc.).
So, you'd probably have to either come up with a clever way to output the log messages you want to output without causing any new-delete to happen, or you will have to restrict your new-delete operator overloads to only the classes of your framework. For the latter, the simplest thing is to put it in a base class. The other option is to use a bit of MACRO magic, but this will still be intrusive and cumbersome.
And, at this point, if you have to create a base-class (for all your library's classes) which handles this logging of creation-deletion (or create a set of MACROs to be put in each class you create), you might as well use the constructor / destructor instead as the place for printing those log messages, and leave the new-delete operators intact.
1- I don't want to use external tools and need to do it in the code.
Why not? It is very likely that an external tool (a VM like Valgrind, or a general profiler / memory tracer) will do a far better and less intrusive job than you will.

Overloading bracket assignment in C++

I am in the process of porting an Objective-C application to C++ and I decided to create a class similar to NSObject and NSDictionary. If you are unfamiliar with this system, an NSObject is an object which all objects inherit form in Obj-C and then there is a reference counting mechanism within it. When there are no more references, the object frees itself.
In my code, I would like to be able to do the following
CMDictionary["Key"] = Object;
Internally, this is stored as
Map<string, CMObject*> mDictionary
Whenever a new object is assigned into the object, the dictionary must then retain this object by calling its retain function as well as calling release on any object that this new object might have replaced. My problem stems from the fact that I cannot find anyway to run code and determine when the brackets are being used in an assignment as I would not want the retain function to be called when I wrote something like
CMDicionary["key"]->StringValue();
Would there by anyway to do this, or would I need to just use getter/setter functions to modify my dictionary
What you typically do in this situation is to implement:
Object const& Map::operator[](string) const;
Object& Map::operator[](string);
Note that I wrote Object& instead of Object. You can at any rate instantiate a new Object and hand it out, relying on a proper Object& Object::operator=(Object const&) to be implemented, which will then perform the assignment, after your Map::operator[] function returns (don't worry, the compiler will optimise it away in most cases).
You should overload the operator[] to accept a string.
http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html
Consider writing a new class similar to shared_ptr<CMObject*> and do the retain/release inside of that object.

I serialized a C++ object, how to allocate memory for it without knowing what type it is?

I have serialized a C++ object and I wish to allocate space for it, although I can't use the "new" operator, because I do not know the object's class. I tried using malloc(sizeof(object)), although trying to typecast the pointer to the type the serialized object is of, the program shut down. Where is the information about the object class stored?
class object
{
public:
virtual void somefunc();
int someint;
};
class objectchild:public object
{
}
object *o=(object*)malloc(sizeof(objectchild));
cout << int(dynamic_cast<objectchild*>(o)) << endl;
This causes a program shutdown.
Thank you in advance.
I have serialized a C++ object
I'm not sure you have. If you've written anything like this:
object *p = new objectchild();
some_file.write((char*)p, sizeof(objectchild));
then you haven't serialized your object. You've written some data to file, and (in most implementations) that data includes a pointer to a vtable and type information. When you "deserialize" the data, on another machine or in another run of the same program, the vtable will not in general be at the same address, and the pointer is useless.
The only way to serialize an object in C++ is to write its data members, in a known format you design. That known format should include enough information to work out the type of the object. There are frameworks that can help you with this, but unlike Java there is no mechanism built into the language or standard libraries.
you should not mix C++ and C memory routes. dynamic_cast checks actual type of object. in your case you have raw memory casted to object *
Rewrite your code so that you can read the type of the object in some way from your serialized archive. You can do this by string or by some custom values you use, but it probably won't be generic.
For example, if you are writing a CFoo object, first stream the value "1". If you are writing a CBar, stream the value "2 .
Then, when reading back the archive, if you see a "1" you know you have to "new" a CFoo, and if you read a "2" you know you have to new a CBar.
Alternatively, you could use a full-featured serialization library (or use it as inspiration).
See for example boost::serialization
You need the following code
object *o = new objectchild;
to use dynamic_cast.
You're trying to dynamic_cast a memory location with nothing in it. malloc has given you free space to place an object, but until the new() operator is called no object is there, so when dynamic_cast does it's type-safety check it will fail. You could try using static_cast rather than dynamic_cast, since static doesn't do a type-safety check, but really you shouldn't mix C and C++ allocation/casting styles like that.