How C++ object keeps information about its member functions - c++

class A {
public :
void printSometext() {
std::cout << "printing A" << std::endl;
}
};
class B {
public :
void printSometext() {
std::cout << "printing B" << std::endl;
}
};
int main() {
A* a = new A();
a->printSometext();
return 0;
}
How C++ object keeps information about its member functions. Lets consider above code. When I call printSometext on object "a" how does it know what function to call and how it finds the right method.
When printing the size of the object it prints the summing size of its member variable (+allignments). So please provide some internal information how the member function call takes place.
Thanks,
Deimus

You have got the basics of C++ programming wrong. a does not know about printSomeText at the runtime, it is the compiler and linker which translates above code to binary code which performs these tasks. At runtime, there is just a bunch of instructions.

Well, that's an interesting question, but let me try to answer that in a very methodical manner !!!
let's say compiler has to resolve a call like this : *
a->someFunc();
*.
Now, compiler will go over following steps methodically.
1.) Firstly, compiler knows the declared type of variable a, so it will check whether the declared type of object a (lets call this, class A for time being), have a method with the name someFunc() and that it must be public. This method could either be declared in class A, or it could be a derived method from one of the base class(es) of class A, but it doesn't matter to compiler and it just checks for it's existence with it's access specifier being public.
Needless to say any error in this step will invite a compiler error.
2.) Secondly, once the method is validated to be a part of the class A, compiler has to resolve the call to the correct method, since many methods could be there with same name (thanks to function overloading). This process of resolving correct method is called overloading resolution. Compiler achieves this by matching the signatures of the called method with all the overloaded methods that are part of the class. So, of all the someFunc() s only the correct someFunc() (matching the signatures with called method) will be found and considered further.
3.) Now comes the difficult part, It may very well happen that someFunc() may have been overridden in one of the subclasses of the class A (lets call this class AA and needless to say it is some subclass of A), and that variable a (declared to be of type A) may actually be referring to an object of class AA, (this is permissible in C++ to enable polymorphism). Now, if the someFunc() method is declared to be of type virtual, in base class (i.e. Class A) and someFunc() has been overriden by subclass(es) of A (either in AA or classes between A and AA), the correct version of someFunc() have to be found out by the compiler.
Now, imagine you're the compiler and you have this task of finding whether the class AA has this method. Obviously, class AA will have this method since, it is a subclass of A and public access of A in class A has already been validated in Step 1 by the compiler !!! . But Alternatively, as mentioned in previous paragraph, someFunc() may be overriden by class AA (or any other class between A and AA), which is what compiler needs to catch. Therefore, you (since, your'e playing the compiler) could do a systematic check to find the bottom-most (lowest in the inheritance tree) overridden method someFunc() starting from class A and ending at class AA. In this search, you'll look for same method signatures as was validated in overloading resolution. This method will be the method which will be invoked.
Now, you may be wondering, "What the heck", is this search done everytime ? ... Well, Not really. The compiler knows the overhead of finding this everytime, and as such, maintains a data-structure called Virtual Table for every class type. Think of virtual table, as mapping from method signatures (which are publicly accessible) to the function pointers. This virtual table is made by compiler during compilation process and is maintained in-memory during program execution. In our example, class A and class AA will both have their own virtual tables. And when compiler has to be find someFunc() in class AA (since actual object pointed by variable a is of type AA), it will simply find the function pointer through the virtual table of Class AA. This is as simple has hashing into the table and is a constant time operation.
Regards
AViD

Adding to the Asha's answer (+1):
If you really want to understand how stuff works internally, I suggest to learn assembly and explore the generated machine code. That's what I did.

The compiler knows the types of the variables. When you use the
. or the -> operator, it looks up the symbol to the left in the
context of the class type of the right hand argument. So in
your example, it only finds A::printSomeText.
--
James Kanze

Related

C++ should I use virtual methods?

Let me start by telling that I understand how virtual methods work (polymorphism, late-binding, vtables).
My question is whether or not I should make my method virtual. I will exemplify my dilemma on a specific case, but any general guidelines will be welcomed too.
The context:
I am creating a library. In this library I have a class CallStack that captures a call stack and then offers vector-like access to the captured stack frames. The capture is done by a protected method CaptureStack. This method could be redefined in a derived class, if the users of the library wish to implement another way to capture the stack. Just to be clear, the discussion to make the method virtual applies only to some methods that I know can be redefined in a derived class (in this case CaptureStack and the destructor), not to all the class methods.
Throughout my library I use CallStack objects, but never exposed as pointers or reference parameters, thus making virtual not needed considering only the use of my library.
And I cannot think of a case when someone would want to use CallStack as pointer or reference to implement polymorphism. If someone wants to derive CallStack and redefine CaptureStack I think just using the derived class object will suffice.
Now just because I cannot think polymorphism will be needed, should I not use virtual methods, or should I use virtual regardless just because a method can be redefined.
Example how CallStack can be used outside my library:
if (error) {
CallStack call_stack; // the constructor calls CaptureStack
for (const auto &stack_frame : call_stack) {
cout << stack_frame << endl;
}
}
A derived class, that redefines CaptureStack could be use in the same manner, not needing polymorphism:
if (error) {
// since this is not a CallStack pointer / reference, virtual would not be needed.
DerivedCallStack d_call_stack;
for (const auto &stack_frame : d_call_stack) {
cout << stack_frame << endl;
}
}
If your library saves the call stack during the constructor then you cannot use virtual methods.
This is C++. One thing people often get wrong when coming to C++ from another language is using virtual methods in constructors. This never works as planned.
C++ sets the virtual function table during each constructor call. That means that functions are never virtual when called from the constructor. The virtual method always points to the current class being constructed.
So even if you did use a virtual method to capture the stack the constructor code would always call the base class method.
To make it work you'd need to take the call out of the constructor and use something like:
CallStack *stack = new DerivedStack;
stack.CaptureStack();
None of your code examples show a good reason to make CaptureStack virtual.
When deciding whether you need a virtual function or not, you need to see if deriving and overriding the function changes the expected behavior/functionality of other functions that you're implementing now or not.
If you are relying on the implementation of that particular function in your other processes of the same class, like another function of the same class, then you might want to have the function as virtual. But if you know what the function is supposed to do in your parent class, and you don't want anybody to change it as far as you're concerned, then it's not a virtual function.
Or as another example, imagine somebody derives a class from you implementation, overrides a function, and passes that object as casted to the parent class to one of your own implemented functions/classes. Would you prefer to have your original implementation of the function or you want them to have you use their own overriden implementation? If the latter is the case, then you should go for virtual, unless not.
It's not clear to me where CallStack is being called. From
your examples, it looks like you're using the template method
pattern, in which the basic functionality is implemented in the
base class, but customized by means of virtual functions
(normally private, not protected) which are provided by the
derived class. In this case (as Peter Bloomfield points out),
the functions must be virtual, since they will be called from
within a member function of the base class; thus, with a static
type of CallStack. However: if I understand your examples
correctly, the call to CallStack will be in the constructor.
This will not work, as during construction of CallStack, the
dynamic type of the object is CallStack, and not
DerivedCallStack, and virtual function calls will resolve to
CallStack.
In such a case, for the use cases you describe, a solution using
templates may be more appropriate. Or even... The name of the
class is clear. I can't think of any reasonable case where
different instances should have different means of capturing the
call stack in a single program. Which suggests that link time
resolution of the type might be appropriate. (I use the
compilation firewall idiom and link time resolution in my own
StackTrace class.)
My question is whether or not I should make my method virtual. I will exemplify my dilemma on a specific case, but any general guidelines will be welcomed too.
Some guidelines:
if you are unsure, you should not do it. Lots of people will tell you that your code should be easily extensible (and as such, virtual), but in practice, most extensible code is never extended, unless you make a library that will be used heavily (see YAGNI principle).
you can use encapsulation in place of inheritance and type polymorphism (templates) as an alternative to class hierarchies in many cases (e.g. std::string and std::wstring are not two concrete implementations of a base string class and they are not inheritable at all).
if (when you are designing your code/public interfaces) you realize you have more than one class that "is an" implementation of another classes' interface, then you should use virtual functions.
You should almost certainly declare the method as virtual.
The first reason is that anything in your base class which calls CaptureStack will be doing so through a base class pointer (i.e. the local this pointer). It will therefore call the base class version of the function, even though a derived class masks it.
Consider the following example:
class Parent
{
public:
void callFoo()
{
foo();
}
void foo()
{
std::cout << "Parent::foo()" << std::endl;
}
};
class Child : public Parent
{
public:
void foo()
{
std::cout << "Child::foo()" << std::endl;
}
};
int main()
{
Child obj;
obj.callFoo();
return 0;
}
The client code using the class is only ever using a derived object (not a base class pointer etc.). However, it's the base class version of foo() that actually gets called. The only way to resolve that is to make foo() virtual.
The second reason is simply one of correct design. If the purpose of the derived class function is to override rather than mask the original, then it should probably do so unless there is a specific reason otherwise (such as performance concerns). If you don't do that, you're inviting bugs and mistakes in future, because the class may not act as expected.

Why "inline" is incompatible with "virtual"

Can someone explain the below paragraph please, no explanation is given:
The reason it works is that, in virtually all implementations of C++,
virtual functions are implemented with a "virtual function table",
which is an array of pointers to functions. This is incompatible
with function inlining because you simply can't have a pointer to
inline code. Thus for most situations, virtual and inline are incompatible; the compiler
will simply ignore the inline statement. However, there is one situation whereby they are
compatible: where the object is accessed directly instead of through a pointer.
"High Performance Game Programming in C++", Paul Pedriana
Can someone please explain why the two sentences in bold are so?
It simply means the compiler won't inline a call it has to resolve at run-time.
Suppose you have
struct A
{
virtual void foo() {};
};
and
void test(A* a)
{
a->foo();
}
This call is resolved at runtime. Since foo() could have been overriden by a deriving class and a could point to an object of a derived type, a->foo() can't be inlined - it will be resolved by a lookup.
The second statement means that virtual functions could be inlined in some situations:
void test(A a)
{
a.foo();
}
In this case, a is of type A (even if the original object passed to the function was a derived type, it was sliced because you passed by value) - the call is guaranteed to call A::foo so it can be inlined by the compiler.
First, the keywords aren't incompatible in any way. The paragraph is discussing the underlying implementation. A particular function call may be either inlined or go through a virtual dispatch, but usually not both. To understand why, you just need to understand what an inline call or a virtual call is.
An inlined function call is one where at least part of the called function is spliced directly into the calling function. This is a low-level optimization that the compiler may perform even on functions that aren't defined as inline. But in the early days when compilers were dumber and executable code size was more important, the keyword was more directly related to the optimization feature.
A virtual call is one where the caller doesn't know exactly what function will be executed. The function's implementation needs to be looked up (dispatched) according to the class at runtime.
So if the function will only be determined at runtime, the compiler cannot splice two functions together. It doesn't know what function would get spliced in.
But you can call a virtual function without making a special dispatch. This occurs if the compiler can be sure of the object's actual type at compile time. For example, if dog is derived from pet with a virtual method speak,
dog fido;
fido.speak(); // direct dispatch: we know fido is a dog.
But this is not the case if we have a reference:
bird buddy;
pet &favorite = prefer_dogs? fido : buddy;
favorite.speak(); // favorite may be a bird or dog: need virtual dispatch
Most of the time, when you call a virtual function you do so through a virtual dispatch.
There is another case, which as far as I know is only theoretical: if the compiler can be sure of the whole class hierarchy (or the choices in a given instance), it could add a Boolean test whether favorite is a bird or a dog and inline both function calls as alternatives in an automatically-generated if … else statement. But anyway, this is just nuts and bolts that you shouldn't worry about.
What's important is that a virtual function is called according to the type the object was defined as, and an inline function may be defined in a header file. And that's all that matters.
It is not "incompatible", just when actually virtual call is placed it is impossible to inline the unknown code. When static call is made to the function inlining will work alright.
The text is not very well formed, but if you already know what it wants to tell, you can find it there. ;-)

What is the most concise yet accurate way to describe what a virtual function is in C++?

Being asked to describe what a virtual function is seems to be one of the most common questions in interviews assessing basic C++ knowledge. However, after several years programming C++, I still have the uncomfortable feeling that I don't really understand how best to define what they are.
If I consult wikipedia, I see the definition of virtual function is:
"In object-oriented programming, a virtual function or virtual method is a function or method whose behaviour can be overridden within an inheriting class by a function with the same signature"
This definition seems simple and elegant, and not C++ specific. But to me it doesn't seem to capture the concept of a virtual function in C++, since surely a non-virtual function can also be overridden within an inheriting class by a function with the same signature.
If I'm asked to describe what a virtual function is informally, I say something about pointers like "it's a method such that when you call it via a base class pointer, the version of it defined in the derived class is called instead, if the pointer actually points to an instance of a derived class". This doesn't seem like a very elegant description of the concept. I know that people say this is how "polymorphism" is achieved in C++ (polymorphism, as far as I understand, roughly being the whole idea of organizing objects into hierarchies), but I don't know of a fancier way to understand or explain the mechanism than to go through the example with the pointers.
I guess I'm confused about whether the "pointer" description of virtual functions is something fundamental to their definition, or just something incidental to their implementation in C++.
I've always thought that this quote captures the essence of virtual functions:
A virtual function is a way of defining a family of related behaviors that can be customized by the entities that actual have to do those behaviors.
If you ignore all the C++-isms of virtual functions - how having virtual functions enables dynamic_cast to work for objects of the class type, how they're only treated virtually if accessed through a pointer, how virtual destructors are completely different from virtual non-destructors, etc. - I think that the above statement gets at the heart of what virtual functions are all about.
The main reason I like this statement is that it describes virtual functions in a way that decouples them from programming. You could explain virtual functions to a non-technical person using this definition by giving some concrete analogies. For example, the idea of "turning on a light" could be thought of as a virtual function because the actual mechanics of what happens when you turn on a light depends entirely on the particular light you're using (incandescent? fluorescent? LED?), but the conceptual idea is the same in each case. Of course, it's not a perfect analogy, but I think it gets the point across well enough.
More generally, IMHO, if you're ever asked to describe something informally, try as much as possible to distance yourself from the particular programming language you're using and, if at all possible, from computers at all. Try to think of the most general setting in which the concept applies, and then describe it at that level. Then again, I teach introductory CS courses, and so I have a bit of a bias toward this domain, so I have no idea how applicable this is in a job interview setting. :-)
since surely a non-virtual function can also be overridden within an inheriting class by a function with the same signature.
No thats incorrect. The function only gets redefined not overriddden in that case.
Your informal definition is a good summary of what a virtual pointer does. It sounds like you're looking to also describe how it works, but since the C++ standard doesn't specify, any "how" description would be specific to a particular implementation and not the C++ language in general.
The C++ standard is all about behavior and says almost nothing about implementation. There's even the "as-if" rule, which allows any alternate implementation that provides the same visible behavior.
"I guess I'm confused about whether the "pointer" description of virtual functions is something fundamental to their definition, or just something incidental to their implementation in C++."
It is not incidental. The concept of virtual functions works only for pointers or references.
Virtual functions are needed when the derived class method bearing the same signature that of base class is overridden to different functionality.
class Polygon
{
public:
virtual float area()
{
std::cout << "\n No formula in general \n" ;
}
virtual ~Polygon();
};
class Square
{
public:
float area()
{
std::cout << "\n Side*Side \n" ;
}
~Square();
}
Polygon* obj = new Square ;
obj -> area() ; // Ok, Square::area() is called.
Square obj1;
Polygon& temp = obj1 ; // Ok, Square::area() is called
Square obj2;
Polygon temp1 = obj2 ; // Polygon::area() is called because of object slicing.
The difference lies in how the compiler decides which implementation to "bind" to the method call when it compiles the source code. For a virtual fumction, the implementation chosen is based on the actual concrete type of the object itself, not on the type of the variable. This means that when you cast an object to a base class or interface, the implementaion which will get executed is still the implementation defined on the derived class that the object actually is.
In puesdo code
// for a virtual function
public class Animal { public virtual void Move() { Print "An animal Moved." } }
public class Dog: Animal { public void Move() { Print "A Dog Moved." } }
Animal x = new Dog();
x.Move() // this will print "A Dog Moved."
For a non-virtual function, the implementation chosen will be based on the type of the variable, which means that when you cast an object to a base class, (i.e., change the type of the variable ) the method implementation defined in the base class will be chosen by the compiler and it will get executed, not the implementation in the derived class...
// for a non-virtual function
public class Animal { public void Move() { Print "An animal Moved." } }
public class Dog: Animal { public void Move() { Print "A Dog Moved." } }
Animal x = new Dog();
x.Move() // this will print "An animal Moved."
Let's say that Beta is a subclass of Alpha, and it can either create a new method area() or it can add a virtual one.
There isn't a difference if you are talking to a Beta pointer. But if you are talking to a Alpha* which points at a Beta object, you will get Alpha's method. Unless you declare the function as virtual.
The Beta subclass has its function dispatch table, which is a copy of Alpha's table but with extra Beta methods at the end. If Beta merely overrides a method, it will go in Beta's section of the dispatch table, so references to Alpha* will not see the new method. But, if the new method is virtual, it will go in the Alpha section of Beta's class table.
More to the point, let's say you have a Circle subclass of Shape. And let's say you have a pointer to a Shape object, x, which happens to be an instance of Circle. x->area() will only see the portion of the function table that relates to Shape. If Circle does a virtual area function, it will appear in the Shape section of the table. If Circle merely overrides area, then the area method will be placed in the Circle portion of the table and the Shape * x will not see the new function.
In C++ there is only one function table per class. This is a bit confusing for people who are used to scripting language where each object has it's own dispatch table. Scripting languages are extremely inefficient in that way. Imagine all the space taken up for each object.
If an interview is about your knowledge in C++ I think there is not a sin to refer to a pointer.
You can say simply that "virtual functions is a mechanism to allow an object to express it's class behavior, even if it's accessed through a base class pointer".
More than this (if you think about "pure virtual functions") it's also a mechanism to force a whole hierarchy of classes to provide a specific method, without defining a default method implementation in the base class.
A virtual function is one where the callee decides the behaviour. A non-virtual function is one where the caller decides the behaviour.
Is that concise enough?
Although pointers are necessary for using virtual functions in C++, I would argue that pointers are incidental to the idea, and explanations that don't depend on pointers are clearer. I think that templatetypedef and Charles_Bretana hit the main idea.
The reason that pointers seem to creep in to descriptions of virtual functions is that only pointers and references can have different run-time vs. compile-time types. A variable whose type is class Foo must contain a Foo at run-time, so it doesn't matter whether a virtual function is used. But a variable whose type is class Foo * can point to any subclass of Foo, so this is the situation where virtual functions and non-virtual functions behave differently.
The Idea
The basic difference between virtual and non virtual method is when you bind the name of the method to the actual method implementation. A virtual method is bound at runtime based on the type. A non virtual function is bound at compile time.
Slightly more formerly:
A virtual method is one that can be overridden in a derived type.
Such that when the virtual method is called (via pointer or reference) runtime binding is applied to select the version of the method that is defined in the most derived version; based on the type of the actual object (being pointed at or referenced).
C++ notes
Note: A method is virtual even if you do not use the virtual keyword if an ancestor declares a method with the same signature as virtual.
Compiler aided mechanism of achieving dynamic polymorphism.
Remember that C++ also supports static polymorphism via generic programming. And function pointers have always been there as the most primitive means of implementing dynamic polymorphism.

Why can't we create objects for an abstract class in C++?

I know it is not allowed in C++, but why? What if it was allowed, what would the problems be?
Judging by your other question, it seems you don't understand how classes operate. Classes are a collection of functions which operate on data.
Functions themselves contain no memory in a class. The following class:
struct dumb_class
{
void foo(){}
void bar(){}
void baz(){}
// .. for all eternity
int i;
};
Has a size of int. No matter how many functions you have ever, this class will only take up the space it takes to operate on an int. When you call a function in this class, the compiler will pass you a pointer to the place where the data in the class is stored; this is the this pointer.
So, the function lie in memory somewhere, loaded once at the beginning of your program, and wait to be called with data to operate on.
Virtual functions are different. The C++ standard does not mandate how the behavior of the virtual functions should go about, only what that behavior should be. Typically, implementations use what's called a virtual table, or vtable for short. A vtable is a table of function pointers, which like normal functions, only get allocated once.
Take this class, and assume our implementor uses vtables:
struct base { virtual void foo(void); };
struct derived { virtual void foo(void); };
The compiler will need to make two vtables, one for base and one for derived. They will look something like this:
typedef /* some generic function pointer type */ func_ptr;
func_ptr __baseTable[] = {&base::foo};
func_ptr __derivedTable[] = {&derived::foo};
How does it use this table? When you create an instance of a class above, the compiler slips in a hidden pointer, which will point to the correct vtable. So when you say:
derived d;
base* b = &d;
b->foo();
Upon executing the last line, it goes to the correct table (__derivedTable in this case), goes to the correct index (0 in this case), and calls that function. As you can see, that will end up calling derived::foo, which is exactly what should happen.
Note, for later, this is the same as doing derived::foo(b), passing b as the this pointer.
So, when virtual methods are present, the class of the size will increase by one pointer (the pointer to the vtable.) Multiple inheritance changes this a bit, but it's mostly the same. You can get more details at C++-FAQ.
Now, to your question. I have:
struct base { virtual void foo(void) = 0; }; // notice the = 0
struct derived { virtual void foo(void); };
and base::foo has no implementation. This makes base::foo a pure abstract function. So, if I were to call it, like above:
derived d;
base* b = &d;
base::foo(b);
What behavior should we expect? Being a pure virtual method, base::foo doesn't even exist. The above code is undefined behavior, and could do anything from nothing to crashing, with anything in between. (Or worse.)
Think about what a pure abstract function represents. Remember, functions take no data, they only describe how to manipulate data. A pure abstract function says: "I want to call this method and have my data be manipulated. How you do this is up to you."
So when you say, "Well, let's call an abstract method", you're replying to the above with: "Up to me? No, you do it." to which it will reply "##^##^". It simply doesn't make sense to tell someone who's saying "do this", "no."
To answer your question directly:
"why we cannot create an object for an abstract class?"
Hopefully you see now, abstract classes only define the functionality the concrete class should be able to do. The abstract class itself is only a blue-print; you don't live in blue-prints, you live in houses that implement the blue-prints.
The problem is simply this:
what should the program do when an abstract method is called?
and even worse: what should be returned for a non-void function?
The application whould proabably have to crash or thow a runtime exception and thus this would cause trouble. You can't dummy-implement every abstract function.
A class can simply be declared abstract where it has no abstract methods. I guess that could be instantiated in theory but the class designer doesn't want you to. It may have unintended consequences.
Usually however abstract classes have abstract methods. They can't be instantiated for the simple reason that they're missing those methods.
Because logically it does not make any sense.
An abstract class is a description that is incomplete.
It indicates what things need to be filled out to make it complete but without those bits its not complete.
My first example was a chess game:
The game has lots of pieces of different type (King,Queen,Pawn ... etc).
But there are no actual objects of type piece, but all objects are instances of objects derived from piece. How can you have an object of something that is not fully defined. There is not point in creating an object of piece as the game does not know how it moves (that is the abstract part). It knows it can move but not how it does it.
Abstract classes are non-instantiable by definition. They require that there be derived, concrete classes. What else would an abstract class be if it didn't have pure virtual (unimplemented) functions?
It's the same class of question as why can't I change the value of a const variable, why can't I access private class members from other classes or why can't I override final methods.
Because that's the purpose of these keywords, to prevent you from doing so. Because the author of the code deemed doing so dangerous, undesired or simply impossible due to some abstract reasons like lack of essential functions that need to be added by specific child classes. It isn't really that you can't instantiate because a class is virtual. It's that inability to instantiate a class defines it as virtual (and if a class that can't be instantiated isn't virtual, it's an error. Same goes the other way, if instance of given class makes sense, it shouldn't be marked as virtual)
Why we cant create an object of an abstract class?
simply abstract class contains abstract methods(means the functions which are without the body) and we cannot give functionality to the abstract methods. And if we try to give functionality to the abstract methods then there will be no difference between abstract class and virtual class. So lastly if we create an object Of an abstrast class then there is no fun to call the useless functions or abstract methods as they are without the functionality..so thats why any language doesnt allow us to create an object of an abstract class..
Abstract classes instantiated would be pretty useless, because you would be seeing a lot more of "pure virtual function called". :)
It's like: we all know that a car would have 3 pedals and a steering wheel and a gear stick. Now, if that would be it, and there'd be an instance of 3 pedals and gear stick and a wheel, I'm not buying it, I want a car, like with seats, doors, AC etc. with pedals actually doing something apart from being in existence and that's what abstract class doesn't promise me, the ones implementing it do.
Basically creation of object is responsible for allocation of memory for member variables and member functions. but here, in pure virtual function we have declaration and defination in derived class.so creation of object generates error.

If classes with virtual functions are implemented with vtables, how is a class with no virtual functions implemented?

In particular, wouldn't there have to be some kind of function pointer in place anyway?
I think that the phrase "classes with virtual functions are implemented with vtables" is misleading you.
The phrase makes it sound like classes with virtual functions are implemented "in way A" and classes without virtual functions are implemented "in way B".
In reality, classes with virtual functions, in addition to being implemented as classes are, they also have a vtable. Another way to see it is that "'vtables' implement the 'virtual function' part of a class".
More details on how they both work:
All classes (with virtual or non-virtual methods) are structs. The only difference between a struct and a class in C++ is that, by default, members are public in structs and private in classes. Because of that, I'll use the term class here to refer to both structs and classes. Remember, they are almost synonyms!
Data Members
Classes are (as are structs) just blocks of contiguous memory where each member is stored in sequence. Note that some times there will be gaps between members for CPU architectural reasons, so the block can be larger than the sum of its parts.
Methods
Methods or "member functions" are an illusion. In reality, there is no such thing as a "member function". A function is always just a sequence of machine code instructions stored somewhere in memory. To make a call, the processor jumps to that position of memory and starts executing. You could say that all methods and functions are 'global', and any indication of the contrary is a convenient illusion enforced by the compiler.
Obviously, a method acts like it belongs to a specific object, so clearly there is more going on. To tie a particular call of a method (a function) to a specific object, every member method has a hidden argument that is a pointer to the object in question. The member is hidden in that you don't add it to your C++ code yourself, but there is nothing magical about it -- it's very real. When you say this:
void CMyThingy::DoSomething(int arg);
{
// do something
}
The compiler really does this:
void CMyThingy_DoSomething(CMyThingy* this, int arg)
{
/do something
}
Finally, when you write this:
myObj.doSomething(aValue);
the compiler says:
CMyThingy_DoSomething(&myObj, aValue);
No need for function pointers anywhere! The compiler knows already which method you are calling so it calls it directly.
Static methods are even simpler. They don't have a this pointer, so they are implemented exactly as you write them.
That's is! The rest is just convenient syntax sugaring: The compiler knows which class a method belongs to, so it makes sure it doesn't let you call the function without specifying which one. It also uses that knowledge to translates myItem to this->myItem when it's unambiguous to do so.
(yeah, that's right: member access in a method is always done indirectly via a pointer, even if you don't see one)
(Edit: Removed last sentence and posted separately so it can be criticized separately)
Non virtual member functions are really just a syntactic sugar as they are almost like an ordinary function but with access checking and an implicit object parameter.
struct A
{
void foo ();
void bar () const;
};
is basically the same as:
struct A
{
};
void foo (A * this);
void bar (A const * this);
The vtable is needed so that we call the right function for our specific object instance. For example, if we have:
struct A
{
virtual void foo ();
};
The implementation of 'foo' might approximate to something like:
void foo (A * this) {
void (*realFoo)(A *) = lookupVtable (this->vtable, "foo");
(realFoo)(this); // Make the call to the most derived version of 'foo'
}
The virtual methods are required when you want to use polymorphism. The virtual modifier puts the method in the VMT for late binding and then at runtime is decided which method from which class is executed.
If the method is not virtual - it is decided at compile time from which class instance will it be executed.
Function pointers are used mostly for callbacks.
If a class with a virtual function is implemented with a vtable, then a class with no virtual function is implemented without a vtable.
A vtable contains the function pointers needed to dispatch a call to the appropriate method. If the method isn't virtual, the call goes to the class's known type, and no indirection is needed.
For a non-virtual method the compiler can generate a normal function invocation (e.g., CALL to a particular address with this pointer passed as a parameter) or even inline it. For a virtual function, the compiler doesn't usually know at compile time at which address to invoke the code, therefore it generates code that looks up the address in the vtable at runtime and then invokes the method. True, even for virtual functions the compiler can sometimes correctly resolve the right code at compile time (e.g., methods on local variables invoked without a pointer/reference).
(I pulled this section from my original answer so that it can be criticized separately. It is a lot more concise and to the point of your question, so in a way it's a much better answer)
No, there are no function pointers; instead, the compiler turns the problem inside-out.
The compiler calls a global function with a pointer to the object instead of calling some pointed-to function inside the object
Why? Because it's usually a lot more efficient that way. Indirect calls are expensive instructions.
There's no need for function pointers as it cant change during the runtime.
Branches are generated directly to the compiled code for the methods; just like if you have functions that aren't in a class at all, branches are generated straight to them.
The compiler/linker links directly which methods will be invoked. No need for a vtable indirection. BTW, what does that have to do with "stack vs. heap"?