Can references be used to implement function overriding?
Can I have a base-class reference that points to a derived-class object, and then get the feature of late binding?
Yes, but polymorphism isn't automatic the way it is in some languages like Java. You have to declare the function virtual in the base class.
Yes. The reason is that, in C++, the derived class object contains a hidden pointer to a record that details the object's actual type. Both the pointer and the record remain, even when a reference binds the object in question.
This assumes, as #Simon observes, that you have declared the function virtual in the base class. (Otherwise, the needed hidden pointer does not exist.)
Related
I know the this pointer will point to the object instance that currently in, but I don't know how to implement it.
And I found that in standard 7.5.2 said:
The keyword this names a pointer to the object for which an implicit object member function ([class.mfct.non.static]) is invoked or a non-static data member's initializer ([class.mem]) is evaluated.
but in 12.2.2 said constructors do not have implicit object parameter, then why I can use this pointer in constructor?
then I have several question comming, so my question is:
Does the this pointer belongs to the class?
I think the answer is NO, but I wanna confirm it.
Does all class instance shared the constructors and destructor?
I knew that the class instance will share the member function, does it same on constructors and destructor?
How the this pointer was implemented?
Is there something like virtual table to maintain the this pointer?
Why I can use the this pointer in constructor?
The this point to the implicit object, but constructor didn't have the implicit object parameter, then how could the this pointer worked well?
Any additional supplements and recommendations are appreciated.
Edit:
This stackoverflow helps me a lot : Does a constructor also have an implicit this parameter
but I don't know how to implement it.
this pointer is a feature of the C++ language. If you aren't implementing C++, then you don't need to "implement" this pointer. If you want to know how to implement C++, there are open source C++ compilers available.
why I can use this pointer in constructor?
Constructor is a non-static member function. You can use this in non-static member functions.
but in 12.2.2 said constructors do not have implicit object parameter
Quoted rule is prefaced: For the purposes of overload resolution.... It doesn't apply to anything other than overload resolution.
Does the this pointer belongs to the class?
There is no concept of "belongs" in the language.
Does all class instance shared the constructors and destructor?
There is no concept of sharing functions in the language.
How the this pointer was implemented?
The language doesn't describe how to implement itself. It describes how the program written in the language shall or may behave.
Why I can use the this pointer in constructor?
See above.
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.
In the class below there is a pointer model_ of type OpModel which is a class. This pointer is initialized in the constructor using new to create an OpModel object. That's fine, you have a pointer to a valid object. The method model() deferences this pointer which access the actual OpModel object. But what I don't understand is that it returns a reference to CompositionalModel which is a different class.
I believe that it is related to polymorphism because OpModel is derived from CompositionalModel, which is an abstract class. But why would you return a reference to the base class?
This is quite a typical thing to do in OO code.
By returning the narrower, base class - think interface - the calling code need only know aboout that.
You can hide all kinds of extra gory, implementation details that way.
Otherwise, any calling code needs to know all about CompositionalModel.
Furthermore, this can change the OpModel to any other type of CompilationUnit and the calling code won't need to change.
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 am reading a book which says:
pass-by-value doesn't work if the function you're sending the argument to has a parameter type which is an abstract base class (ABC). You have to pass the argument (which would be a derived class) by reference.
My questions are:
Why can you not pass the derived class argument by value?
Is there something "internal" to C++ which requires it to be a reference?
Is this to do with the way dynamic binding works?
This is because of object slicing: the abstract class received by value will receive a copy of the object that you are passing; therefore, the derived data members will be sliced off from it, making the object unusable.
When you pass by reference, you are passing the address of the existing object, which is a member of a derived class, all its data members included. This is not specific to C++ - this is a property of passing by value in general.
The dynamic binding is implemented in such a way as to not allow sliced instance receive calls as if it were a complete instance. The vtable pointer is adjusted to dispatch the calls to the member functions of the abstract base class.
Why can you not pass the derived class argument by value?
Simply put, if you have a function that looks like this:
void foo(T t); // Takes a T by value
And you call it this way (whatever v is):
foo(v);
What happens is that the parameter t represents a new object which is copy-initialized from the argument v, as if you were doing:
T t = v;
Now if T is abstract, the above is illegal, because you cannot instantiate an abstract class (by definition). Therefore, the parameter of foo() cannot be copy-initialized from its argument.
Is there something "internal" to C++ which requires it to be a reference?
Something like that. Dynamic polymorphism in C++ can only work through references and pointers. When you try to assign an object of a derived class to an object of a base class, what you get is object slicing.
You can pass a derived class by value. You cannot pass the abstract base class as an argument by value because there is no way to instantiate an abstract class.
In general you want to pass by reference or pointers so you do not slice the object. There is a good answer here: What is object slicing?
When you receive an object by value, its dymanic (its "real" type) type is its static type. It is not possible to have a variable whose dynamic type is an abstract one. No matter how you build it.