Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Actually, it's my final term exam question.
Which of the following will create a compile time error?
Declaring object of a concrete class in the definition of main function.
Writing output statement, in constructor statement.
Declaring object of a class having at least one virtual function.
Declaring objects of a class having all virtual functions.
I've chosen 4th one. But still confused. Need help!
Some questions might be interpretable differently, so I will sum those up here. Note however, that some of these interpretations are not actually synonymes, but just my thoughts on what your teacher could have meant to say.
1. Declaring object of a concrete class in the definition of main function.
See this question: What is the difference between a concrete class and an abstract class?.
This shows it is valid to instantiate or declare a concrete class. The main function is no special exception to this.
Conclusion: this is valid.
2. Writing output statement, in constructor statement.
By constructor statement, I assume the constructor function of a class or struct, or something alike, is meant. Usually, I would say that an output statement is something like writing to the console. However, as the questions use kind of weird language anyway, one could say that by output statement the return statement is meant.
Output, as in writing to the console for example, is perfectly legal in a constructor function.
class Foo
{
public:
Foo()
{
std::cout << "I made a Foo\n";
}
}
Output, as in returning something from a function, is not legal in a constructor.
class Foo
{
public:
Foo()
{
return 3; // not legal
}
}
Conclusion: If this is valid or not depends on how you interpret the question.
3. Declaring object of a class having at least one virtual function.
Virtual functions in classes are explained here: C++ Virtual/Pure Virtual Explained.
The question is clear in that the one or more virtual function are not pure virtual, so:
Conclusion: this is valid.
4. Declaring objects of a class having all virtual functions.
See my explanation of answer 3 for an explanation of virtual and pure virtual functions.
The straightforward interpretation of this answer is: Is it legal to declare an object of a class of which all functions are virtual? In this case the statement is valid, see answer 3.
However, you could interpret all virtual functions as pure virtual functions, in which case instantiating the class is not valid.
Conclusion: If this is valid or not depends on how you interpret the question.
Final conclusion
Answer 1 and 3 both describe valid C++. However, answer 2 and 4 can be interpreted in multiple ways, so the answer is not clear.
Personal thought
I have never ever heard of someone calling a return statement an output statement. Neither have I heard of someone calling a pure virtual function an all virtual function. I think your teacher is weird.
None of the four options
Declaring object of a concrete class in the definition of main function.
Writing output statement, in constructor statement.
Declaring object of a class having at least one virtual function.
Declaring objects of a class having all virtual functions
would necessarily give a compilation error.
Any of them would give a compilation error if you include a syntax error, say.
However, it's unclear what the author means by "constructor statement", that's not a standard term.
It's possible that by "all virtual functions" the author means "one or more pure virtual functions". If so then then that's probably the intended answer.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am pretty new to both the OOP and the C++ language.
Recently I have been given the task of come up with an object oriented design -which I guess I have done quite ok so far considering my lack of knowledge on the subject. And since I want to keep performing either like I have done so far or better, I want to get my doubt cleared.
I made a design in which the base class offers two virtual functions. Some children implements both virtual functions of their parent, but some others implement only one.
Now, I know that it is not the best / clean design somebody can come up with, and that if I do not implement (in some children) one of these virtual methods I might get warnings from the compiler. I know I can implement the methods, and when they are not needed they could simply return an exception, or simply do nothing.
With all that said, my doubt/question is: What is the actual risk of not implementing one of these virtual methods in the children? What happens on the object which does not have a virtual method's implementation of its parent? I am looking for a rather deep insight - I mean, I am looking for an understanding on a object's guts level so to say.
If an explanation is not possible to be given, any reference where to possible look at will be equally Welcomed and appreciated.
Cheers!
EDIT
Hi. Thanks everyone for your answers. My initial question -at least in my head- was not related to "Possible duplicate" suggested by Viktor Chvátal - but this question he pointed at, ALONG WITH all the other answers to my question clarified and dissipated my doubt. At the beginning, I though that if child does not implement the virtual method from parent, there would be some sort of "hole" there, where a method (or pointer to method, or whatever) should be. But then what would happen is that the child would be using the parent's implementation.
Thanks everyone and sorry for the fuss of asking something which is apparently already answered somewhere else. The thing is I should read more about how stuff works, before giving somebody else's comments as granted - wich is what took me to ask this question in the first place.
I'll try no to repeat this mistake in the future.
That is not the correct question to be asking. The correct question is if the child class only overrides one or two of the functions it is allowed to override then the question is "Should my child class be deriving from the parent class". For example of a bad inheritance is:
class shape
{
public:
virtual void draw();
virtual void print();
};
class log : public shape
{
public:
void print() override;
};
This is a bad inheritance as the two both need a print method but a log class has nothing to do with drawing nor is it related to a shape. Is it dangerous not in the context of security but in the sense that anyone using your code will be extremely confused it is.
An example of a better inheritance would be:
class shape
{
public:
virtual void draw() = 0;
};
class rectangle : public shape
{
virtual void draw();
};
Here square inherits from shape as a rectangle is a shape and the inheritance enforces rectangle to define a draw method. With this inheritance it is very clear as to what is going on and there is no risk involved.
Some children implements both virtual functions of their parent, but
some others implement only one
That is perfectly fine, and that's one of the reasons virtual methods differ from abstract ones, former being optional to be overridden in more specific types (child classes).
I know I can implement the methods, and when they are not needed they
could simply return an exception, or simply do nothing
Throwing exception, say not implemeted or supported, is bad idea. If you knew the specific type would not support specific behavior, that behavior should not be part of base class itself. You should implement such behaviors (which are specific to some derived classes) using interfaces instead.
You might be confusing virtual methods with pure virtual methods.
A virtual method is just a regular method that children classes can override, which means "swap the default behavior for a custom one".
You declare them like this:
virtual ReturnType myVirtualMethod();
Pure virtual methods, on the other hand require you to implement them in the child class. They are used when no sensible default behavior can be written within the parent class. In case you don't implement them, the child class will fail to compile, which is good, because it prevents undefined behavior - in this case: what should run when NO method was provided? It is impossible for the compiler to decide.
They can be declared with this syntax:
virtual ReturnType myVirtualMethod() = 0; // notice the "= 0" at the end
So I think the question you should ask yourself is this one: "can I provide any default behavior that works in most cases for this method?" If not, you should consider making the method pure virtual, otherwise implement the default behavior in the parent class, and don't bother overriding that method in child classes that don't need it.
Hope this helped!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Well my question is a bit trickier.
Let's say I have three classes like so:
class GrandFather
{
public:
virtual int DoSomething()
{
return 3;
}
};
class Father : public GrandFather
{
};
class Child : public Father
{
public:
virtual int DoSomething()
{
Father::DoSomething();
}
};
I have found in some references, that when calling a base function, the whole virtual mechanism isn't used, and name mangling takes place.
Now I want to know how this could be done.
The Child class has a pointer to its own vtable, which will indicate that upon calling DoSomething() the implementation of the child is called.
The Father class has a pointer to its own vtable as well, which will indicate that upon calling DoSomething() the implementation of GrandFather is called.
When I use Father::DoSomething() inside of Child, it should call GrandFather::DoSomething(),
but how can Child tell where the function is?
If name mangling is really used, then how? because there is no function with that name (something like _Father_DoSomething(this)).
Child must access the Father's vptr in order to get to GrandFather::DoSomething() , which as much as I know, he cannot.
This has been bothering me for quite some time, so I will appreciate the help very much.
thanks :)
Whenever you explicitly qualify the member function, you are saying you want to call that particular function in that particular class, and the virtual calling mechanism isn't used. Virtual calls only take place when you call a member function without qualifying it, it which case it uses the virtual mechanism to make the decision about which class's member function to use.
The fact that calling Father::DoSomething calls GrandFather::DoSomething is due to inheritance, which is a separate mechanism. If you refer to a member of the derived class and it isn't there, it goes up one level and looks in the base class for it. No virtual call is necessary there.
When you call Father::DoSomething from Child the compiler used compile time information to work out what to call. Because there isn't a version in Father it knows to call the one in GrandFather as it's the version that is effectivly in scope within Father.
When an overridden method calls down to a base implementation the vtable isn't used. The vtable is only used when you call a method via a pointer or reference. This is how all polymorphism is achieved in C++.
Name mangling doesn't have anything to do with this. Name mangling is basically how a method name is encoded so give a unique name for a method/function. No two methods/functions will have the same mangled name.
When a qualified name is used to name the function, the function
called is determined at compile time, using the static type of
the expression, and the name lookup starts at the location given
by the qualifier. Since the function to be called is determined
entirely by static lookup, there is no need to access any vtable
at all.
The g++ file_name.cpp -S command could provide enough info to have all vtable-related issues clear. Please check .s file produced:
Child has own vtable that contains Father vtable that, in own turn, contains vtable for GrandFather:
vtable for Child:
Child::DoSomething()
vtable for Father
vtable for Father:
GrandFather::DoSomething()
vtable for GrandFather
vtable for GrandFather:
GrandFather::DoSomething()
When I use Father::DoSomething() inside of Child, it should call
GrandFather::DoSomething(), but how can Child tell where the function
is?
vtable for Father has reference to the GrandFather::DoSomething(), so calling Father::DoSomething() you are actualli invoking GrandFather::DoSomething()
"Name mangling" has absolutely nothing to do with it. The technique known as "name mangling" belongs to completely different and irrelevant area. I don't know where you got the idea to involve it here.
Classes do not have any "pointers to vtable". Only specific objects (aka instances) of class types might have such pointers. Don't mix classes and objects of class type. In any case, "vtable pointers" is an implementation detail that does not exist at language level. It is completely unnecessary for understanding the behavior of the code at language level.
In your example you don't have any objects at all. You simply declared a bunch of classes. For this reason, it is to early to be taking about any "pointers to vtables". You don't have any pointers to any vtables in what you posted.
When it comes to the matter of Father::DoSomething() call, the issue of any "virtual tables" does not come into the picture at all, even as an implementation detail. Father::DoSomething() call uses a qualified name of the target function. Such qualified calls are always resolved directly, without involving any vtables. I.e. by doing Father::DoSomething() you are explicitly asking the compiler to ignore any polymorphism (ignore any "vtables") and directly perform a compile-time name lookup for name DoSomething in class Father. According to the rules of name lookup it will find function GrandFather::DoSomething() and call it.
If you actually declare an object, like
Child child;
then you will have a GrandFather subobject embedded into Father subobject embedded into the above Child object. All "vtable pointers" in those nested objects will point to the vtable of Child (in fact, in a typical implementation all these nested objects will share a single vtable pointer).
Now if you call
child.DoSomething()
this call will be resolved in accordance with vtable of Child and dispatched to Child::DoSomething() (most compilers will actually be smart enough to optimize the code and dispatch the call directly). However, as I said above, the qualified call to Father::DoSomething from inside Child::DoSomething is unconditionally performed directly, as you asked. It doesn't care about any vtable pointers. It just goes straight to GrandFather::DoSomething().
That's all there is to it.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
What's the difference between the following 4 styles of calling another member function?
Is there a benefit that causes that one method is preferrable?
void Object::trigger() {
(*this).triggerinner(10);
this->triggerinner(10);
triggerinner(10);
Object::triggerinner(10);
}
void Object::triggerinner(int x) {
std::cout << "trigger" << std::endl;
}
The first three are fundamentally the same in non-template code.
In a template member function, the first two make the name
lookup dependent (so the compiler can find names in a dependent
base class). Generally, simpler is better, so most people favor
the third form, except when the dependend lookup is necessary,
in which case they will use the second.
The fourth form blocks virtual resolution. (And it has, in
fact, the same three forms as above, i.e.
this->Object::triggerinner(10), etc.) You use it when you
want to force the resolution: the function called will be in
Object or in a base class of Object, but never in a derived
class, even if the function is virtual. This is most often used
in a derived class, to call the base class implementation before
(or after) doing additional work:
void
Derived::func()
{
Base::func();
// Additional work here...
}
Outside of a member function, it can also be used to call
a static member function when you don't have an object.
The first two are exactly equivalent to each other. By definition, (*p).thing and p->thing are equivalent for any pointer.
The third is equivalent in this situation; but could have a different meaning if the member function's name were hidden by a local declaration. There are also situations (where the function is a member of a base class, and templates are involved) when this form won't find the function, in which case you would have to use one of the others.
The fourth is equivalent if the function is not virtual. If it is virtual, then this will force a non-virtual call to the override available in this class, rather than the final override.
(*this).triggerinner(10);
It's ugly, "->" is there to avoid to do that.
this->triggerinner(10);
It's fine but this-> is not mandatory. If you are working on an existing project, keep the current coding style.
triggerinner(10);
It's fine, same comment than the solution using this->.
Object::triggerinner(10);
Use this for static methods.
I would suggest you to use triggerinner(10) since it's short and clear.
the most frequently used one is this->triggerinner(10);.The reason it makes an easy match using the pointer with table.
this->triggerinner(10) is better than the others:
Better than (*this).triggerinner(10) because it is more readable.
better than triggerinner(10), because in this case you will not know if triggerinner() is a method or a function (with a different scope then).
Better than Object::triggerinner(10) which is mainly used for static methods (but not only)
There is no difference, unless your compiler does some funky stuff. Try reading the assembly language generated by the lines in your function and see if there are any differences or if its the same block of instructions generated over and over.
As for the "best" or " most popular" one that comes down to your personal preference or when working at a company they might enforce certain coding standards forcing you to write in a specific way when doing something every time.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can a member function template be virtual?
In a base class, the function my_func is defined as virtual. However, in the derived class I would like to have my_func to be a template method. Is this possible?
It seems it isn't. I get the error "cannot allocate an object of abstract type", which I believe it is related to the fact that the compiler does not acknowledge the override of the virtual my_func in the base class. Does this reveal a poor design maybe?
Thanks a lot.
UPDATE:
Thanks for the answers. Some of you are suggesting I should post some of the code, so here it is.
In the base class:
virtual void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met) = 0;
But in the derived class I would like to have:
template<typename _Jet>
void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons_in, vector<Electron*>& electrons_in, vector<_Jet>& jets_in, LorentzM& met){
From your answers, I understand that a solution to the problem would be to define another function in the derived class:
void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met){
//
}
but then, this function and the template function are the same for the case of _Jet being Jet*, wouldn't that be a problem as well?
Some have suggested a design problem here, I guess that's true, I'll have to think about how to go around this then.
Your templated method overloads the original (same name but different parameters). You still have to override the original as well, to make your derived class non-abstract. You can do both no problem, so you will have two versions of the method in the derived class, just be careful and conscious of which one will get called...
You can then make the overriden overload version of method to call the new template overload version. This may or may not do what you want to achieve, depending on what you want to achieve...
It might still be better for the template method to have a different name, to avoid confusion, because you can not call it directly anyway, unless you have pointer of the derived class type. If you have pointer to the abstract base class, you must call the method with the parameters defined there, even if it is virtual method and a derived class method is what actually gets called.
The problem is that the template is changing the signature of the function, so it's no longer overriding the virtual function in the base class, therefore you class continues to be abstract.
Templating a virtual function seems to defeat the polymorphic nature of the virtual function in the base class.
The function in the derived class needs to have the same signature in order to properly override the function of your base class (and get rid of the abstract type error).
That means :
same name
same parameter number and types
same qualifiers (constness for example)
compatible return types (even though that's technically not part of the signature iirc)
So indeed, using template in that case can lead to that kind of error. The best would be to post a code sample so people could get a better idea of your specific case.
You can’t do that because the my_func template version is not covariant with the base class one. It’s a design problem you have here, btw.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
C++ Virtual/Pure Virtual Explained
What's the difference between virtual function instantiations in c++
Why pure virtual function is initialized by 0?
This is a method in some class declaration that someone gave me. And I don't know what '..=0' means. What is it?
virtual void Print() const = 0;
The = 0 makes the function pure virtual, rendering the class an abstract class.
An abstract class basically is a kind of interface, which derived classes need to implement in order to be instantiable. However, there's much more to this, and it is some of the very basics of object-oriented programming in C++. If you don't know these, you need to go back to the textbook and read up. There's no way you can advance without understanding them.
That said, see this related question for some explanations of what virtual and pure virtual functions are. And as always, the C++ FAQ is an excellent resource for such questions.
It means that the virtual function is pure, meaning that you cannot call it as such: the function doesn't have any code to it, hence the = 0. Only by deriving the class and overriding the function you can call it. The class with pure virtual functions cannot be instantiated so they are called abstract classes, interfaces in some languages.
Basically, it means the function has no code. This means that you cannot use instances of this class. Rather, it can only be a base class.