How can I create a pointer to a class. I assume, that classes exists somewhere in RAM, so, is it possible to get a pointer to it?
I don't mean a pointer to an object, I mean a pointer to the class itself (like a function pointer).
I assume, that classes exist somewhere in the Ram
Classes do not exist at run-time, so you cannot take a pointer to a class.
Only objects exist at run-time.
This is not possible. C++ has three types of pointers:
Pointers to objects
Pointers to functions
Pointers to class members.
Classes are none of the above.
Related
I was just curious, does the creation of an object in C++ allocate space for a new copy of it's member functions? At the assembly or machine code level, where no classes exist, do all calls for a specific function from different objects of the same class actually refer to the same function pointer or are there multiple function blocks in memory and therefore different pointers for each and every member function of every object derived from the same class?
Usually languages implement functionalities as simply as possible.
Class methods are under the hood just simple functions containing object pointer as an argument, where object in fact is just data structure + functions that can operate on this data structure.
Normally compiler knows which function should operate on the object.
However if there is a case of polymorphism where function may be overriden.
Then compiler doesn't know what is the type of class, it may be Derived1 or Derived2.
Then compiler will add a VTable to this object that will contain function pointers to functions that could have been overridden.
Then for overridable methods the program will make a lookup in this table to see which function should be executed.
You can see how it can be implemented by seeing how polymorphism can be implemented in C:
How can I simulate OO-style polymorphism in C?
No, it does not. Functions are class-wide. When you allocate an object in C++ it will contain space for all its attributes plus a VTable with pointers to all its methods/functions, be it from its own class or inherited from parent classes.
When you call a method on that object, you essentially perform a look-up on that VTable and the appropriate method is called.
When using C-libraries it might be appropopriate to derive a class from a C-structure and add some methods to operate on it without any data-members. F.e. you could add a constructor to initialize the members more conveniently. So this objects might be implicitly upcasted and passed to the C-APIs.
There might be cases where the API expects an array of the C-structures. But is there any guarantee of the C++-language that the derived objectds have the same size as the base-struct so that the distances between the objects are properly offsetted?
BTW: None of the suggestions of similar questions matches my question.
In general, there is no such guarantee. And in particular, if you introduce virtual member functions for example, then there would typically be additional memory used for the virtual table pointer.
If we add an additional assumption that the derived class is standard layout, and no non-standard features such as "packing" is used, then the size would be the same in practice.
However, even if the size is the same, you technically cannot pretend that an array of derived type is an array of base type. In particular, iterating the "pretended" array with a pointer to base would have undefined behaviour. At least that's how it is within C++. Those operations are presumably performed in C across the API. I really don't know what guarantees there are in that case.
I would recommend that if you need to deal with arrays of the C struct (i.e. the pointer would be incremented or subscripted by the API), then instead of wrapping the individual struct, create a C++ wrapper for the entire array.
But is there any guarantee of the C++-language that the derived objectds have the same size as the base-stuct
In general I would expect, that the class will not add any additional to the class memory layout, as long you did not introduce new data members or virtual functions. Use of virtual functions results in adding the v-table pointer.
The implementation is also free to add a v-table pointer if you use virtual inheritance. This will also change the layout for most compilers ( clang and c++ use a vtable in that case! )
But this all is implementation specific and I did not know of a guarantee in the C++ standards which defines that the class layout will guarantee that you can use a derived class without a cast operation as the base class.
You also have to think of padding of data structures which may be different for the derived class.
Generate something ( the derived class ) and use it as something different ( the base struct ) is in general undefined behavior. We are not talking of cast operations! If you cast the derived class to the base class, everything is fine. But packing many instances into a derived class array and simply use it as a base class array is undefined behavior.
In C++ is it true that if you instantiate an object of a class, that for every
object all of methods of the class are copied for the new object?
I tried to point to a method of a class with two different objects, but I'd problems
with pointer to member.
Any idea?
In C++ is it true that if you instantiate an object of a class, that for every object all of methods of the class are copied for the new object?
No, member functions are not usually copied anywhere. A different implicit parameter this is instead passed to any non-static member function, for each object of that class-type.
No, that is absolutely not true.
Class instances (objects) contain data members. Function members look like they're "in" the class, but that's only for scoping and such: your function code doesn't "exist" inside the type, and it certainly doesn't exist inside the object†.
†I think it could, theoretically, in that the standard doesn't outright forbid it. But honestly, no. Just no.
The code for a class exists only once.
For getting a pointer to a member function (probably what you meant by method), take a look at std::function, and for attaching the function call to different objects, take a look at std::bind.
I found below post
C++ polymorphism without pointers
that explains to have polymorphism feature C++ must use pointer or reference types.
I looked into some further resources all of them says the same but the reason .
Is there any technical difficulty to support polymorphism with values or it is possible but C++ have decided to not to provide that ability ?
The problem with treating values polymorphically boils down to the object slicing issue: since derived objects could use more memory than their base class, declaring a value in the automatic storage (i.e. on the stack) leads to allocating memory only for the base, not for the derived object. Therefore, parts of the object that belong to the derived class may be sliced off. That is why C++ designers made a conscious decision to re-route virtual member-functions to the implementations in the base class, which cannot touch the data members of the derived class.
The difficulty comes from the fact that what you call objects are allocated in automatic memory (on the stack) and the size must be known at compile-time.
Size of pointers are known at compile-time regardless of what they point to, and references are implemented as pointers under the hood, so no worries there.
Consider objects though:
BaseObject obj = ObjectFactory::createDerived();
How much memory should be allocated for obj if createDerived() conditionally returns derived objects? To overcome this, the object returned is sliced and "converted* to a BaseObject whose size is known.
This all stems from the "pay for what you use" mentality.
The short answer is because the standard specifies it. But are there any insurmountable technical barriers to allowing it?
C++ data structures have known size. Polymorphism typically requires that the data structures can vary in size. In general, you cannot store a different (larger) type within the storage of a smaller type, so storing a child class with extra variables (or other reasons to be larger) within storage for a parent class is not generally possible.
Now, we can get around this. We can create a buffer larger than what is required to store the parent class, and construct child classes within that buffer: but in this case, exposure to said instance will be via references, and you will carefully wrap the class.
This is similar to the technique known as "small object optimization" used by boost::any, boost::variant and many implementations of std::string, where we store (by value) objects in a buffer within a class and manage their lifetime manually.
There is also an issue where Derived pointers to an instance can have different values than Base pointers to an instance: value instances of objects in C++ are presumed to exist where the storage for the instance starts by most implementations.
So in theory, C++ could allow polymorphic instances if we restricted it to derived classes that could be stored in the same memory footprint, with the same "pointer to" value for both Derived and Base, but this would be an extremely narrow corner case, and could reduce the kinds of optimizations and assumptions compilers could make about value instances of a class in nearly every case! (Right now, the compiler can assume that value instances of a class C have virtual methods that are not overridden elsewhere, as an example) That is a non trivial cost for an extremely marginal benefit.
What more, we are capable of using the C++ language to emulate this corner case using existing language features (placement new, references, and manual destruction) if we really need it, without imposing that above cost.
It is not immediately clear what you mean by "polymorphism with values". In C++ when you have an object of type A, it always behaves as an object of type A. This is perfectly normal and logical thing to expect. I don't see how it can possible behave in any other way. So, it is not clear what "ability" that someone decided "not to provide" you are talking about.
Polymorphism in C++ means one thing: virtual function calls made through an expression with polymorphic type are resolved in accordance with the dynamic type of that expression (as opposed to static type for non-virtual functions). That's all there is to it.
Polymorphism in C++ always works in accordance with the above rule. It works that way through pointers. It works that way through references. It works that way through immediate objects ("values" as you called them). So, it not not correct to say that polymorphism in C++ only works with pointers and references. It works with "values" as well. They all follow the same rule, as stated above.
However, for an immediate object (a "value") its dynamic type is always the same as it static type. So, even though polymorphism works for immediate values, it does not demonstrate anything truly "polymorphic". The behavior of an immediate object with polymorphism is the same as it would be without polymorphism. So, polymorphism of an immediate object is degenerate, trivial polymorphism. It exists only conceptually. This is, again, perfectly logical: an object of type A should behave as an object of type A. How else can it behave?
In order to observe the actual non-degenerate polymorphism, one needs an expression whose static type is different from its dynamic type. Non-trivial polymorphism is observed when an expression of static type A behaves (with regard to virtual function calls) as an object of different type B. For this an expression of static type A must actually refer to an object of type B. This is only possible with pointers or references. The only way to create that difference between static and dynamic type of an expression is through using pointers or references.
In other words, its not correct to say that polymorphism in C++ only works through pointers or references. It is correct to say is that with pointers or references polymorphism becomes observable and non-trivial.
I'm not talking about a pointer to an instance, I want a pointer to a class itself.
In C++, classes are not "first class objects". The closest you can get is a pointer to its type_info instance.
No. A pointer is the address of something in the memory of the computer at run-time. A class is just a set of instructions to the compiler.
As everyone else have already said, it's not possible to have a pointer to a class.
But if the point is to create a new instance from some class chosen at runtime, you might want to check out the Factory Method (or Abstract Factory) design patterns.
Yes and No. This depends on your context of what you are trying to achieve. If you simply want a pointer to a type then no there is not a way. A type does not live in memory in the sense of a pointer.
There reason I said yes though is some people would consider the virtual table a pointer to a type. It is possible to get this pointer since the virtual table does exist in memory and can be used to invoke virtual methods with a bit of trickery.
Unlike true Object-Based languages, a class is not an object in C++, more is the pity. The closest you can come to "pointer to class" is RTTI:
const std::type_info &info = typeid(object expression);
type_info has name() member finction, and they can be compared to each other.
A "Class" does not exist. The only thing you can point to is the data.
The rest of a "Class" is actually a dispatch table. For each method in the class, the dispatch table has a pointer. That way, the class points to the correct method of your class regardless of what type it's currently cast to. This would be useless to access.
Methods in your class (the things pointed to by the dispatch table) are actually just "Functions" that are passed in your class data pointer. The definition of a method is pretty much that it's a function that takes the classes data as a parameter. In most C-style languages, that data pointer is hidden but referred to as "this".
The methods for your class may be spread all over the codebase. Because of parent classes, you're not likely even find these methods adjacent to each other.
You can't have a (run-time) pointer to a class, but C++ does has a similar compile-time concept: template parameters. Boost has a library dedicated to manipulating them and a traits library for getting information about classes.
Depending upon how you want to think about pointers, you can have a "pointer" to a class, if by pointer you mean some integral value. Boost allows you to register types and assign a unique integer for every type that you register. If the types you are registering are all classes then you can look up at run-time the code necessary to create an object of the type you want, as long as you have the value of the type you want. But in general, classes aren't first class objects in the language and the best you can hope for is to simulate the behavior you want to have.
True, there is no support for reflection/introspection in built in to C++, but there are a number of libraries that will add many of eg java's Class functionality, and allow a programmer to get an object representing a class, create an instance, etc. google c++ reflection.