What is C++?C++ is a programming language. It literally means "increased C", reflecting its nature as an evolution of the C language.
Is it necessary to already know another programming language before learning C++?Not necessarily. C++ is a simple and clear language in its expressions. It is true that a piece of code written with C++ may be seen by a stranger of programming a bit more cryptic than some other languages due to the intensive use of special characters ({}[]*&!|...), but once one knows the meaning of such characters it can be even more schematic and clear than other languages that rely more on English words.
Also, the simplification of the input/output interface of C++ in comparison to C and the incorporation of the standard template library in the language, makes the communication and manipulation of data in a program written in C++ as simple as in other languages, without losing the power it offers.
How can I learn C++?There are many ways. Depending on the time you have and your preferences. The language is taught in many types of academic forms throughout the world, and can also be learn by oneself with the help of tutorials and books. The documentation section of this Website contains an online tutorial to help you achieve the objective of learning this language.
What is OOP: Object-oriented programming? It is a programming model that treats programming from a perspective where each component is considered an object, with its own properties and methods, replacing or complementing structured programming paradigm, where the focus was on procedures and parameters.
What is ANSI-C++? ANSI-C++ is the name by which the international ANSI/ISO standard for the C++ language is known. But before this standard was published, C++ was already widely used and therefore there is a lot of code out there written in pre-standard C++. Referring to ANSI-C++ explicitly differentiate it from pre-standard C++ code, which is incompatible in some ways.
What is Visual C++? And what does "visual programming" mean?Visual C++ is the name of a C++ compiler with an integrated environment from Microsoft. It includes special tools that simplify the development of large applications as well as specific libraries that improve productivity. The use of these tools is generally known as visual programming. Other manufacturers also develop these types of tools and libraries, like Borland C++, Visual Age, etc...
Is C++ a practical language?Yes.
C++ is a practical tool. It's not perfect, but it's useful.
In the world of industrial software, C++ is viewed as a solid, mature, mainstream tool. It has widespread industry support which makes it "good" from an overall business perspective.
Is C++ a perfect language?Nope.
C++ wasn't designed to demonstrate what a perfect OO language looks like. It was designed to be a practical tool for solving real world problems. It has a few warts, but the only place where it's appropriate to keep fiddling with something until it's perfect is in a pure academic setting. That wasn't C++'s goal.
What's the big deal with OO?Object-oriented techniques are the best way we know of to develop large, complex software applications and systems.
OO hype: the software industry is "failing" to meet demands for large, complex software systems. But this "failure" is actually due to our successes: our successes have propelled users to ask for more. Unfortunately we created a market hunger that the "structured" analysis, design and programming techniques couldn't satisfy. This required us to create a better paradigm.
C++ is an OO programming language. C++ can also be used as a traditional programming language (as "as a better C"). However if you use it "as a better C," don't expect to get the benefits of object-oriented programming.
What is a class?The fundamental building block of OO software.
A class defines a data type, much like a struct would be in C. In a computer science sense, a type consists of both a set of states and a set of operations which transition between those states. Thus int is a type because it has both a set of states and it has operations like i + j or i++, etc. In exactly the same way, a class provides a set of (usually public:) operations, and a set of (usually non-public:) data bits representing the abstract values that instances of the type can have.
You can imagine that int is a class that has member functions called operator++, etc. (int isn't really a class, but the basic analogy is this: a class is a type, much like int is a type.)
Note: a C programmer can think of a class as a C struct whose members default to private. But if that's all you think of a class, then you probably need to experience a personal paradigm shift.
What is an object?A region of storage with associated semantics.
After the declaration int i; we say that "i is an object of type int." In OO/C++, "object" usually means "an instance of a class." Thus a class defines the behavior of possibly many objects (instances).
When is an interface "good"?When it provides a simplified view of a chunk of software, and it is expressed in the vocabulary of a user (where a "chunk" is normally a class or a tight group of classes, and a "user" is another developer rather than the ultimate customer).
What is encapsulation?Preventing unauthorized access to some piece of information or functionality.
The key money-saving insight is to separate the volatile part of some chunk of software from the stable part. Encapsulation puts a firewall around the chunk, which prevents other chunks from accessing the volatile parts; other chunks can only access the stable parts. This prevents the other chunks from breaking if (when!) the volatile parts are changed. In context of OO software, a "chunk" is normally a class or a tight group of classes.
The "volatile parts" are the implementation details. If the chunk is a single class, the volatile part is normally encapsulated using the private: and/or protected: keywords. If the chunk is a tight group of classes, encapsulation can be used to deny access to entire classes in that group. Inheritance can also be used as a form of encapsulation.
The "stable parts" are the interfaces. A good interface provides a simplified view in the vocabulary of a user, and is designed from the outside-in (here a "user" means another developer, not the end-user who buys the completed application). If the chunk is a single class, the interface is simply the class's public: member functions and friend functions. If the chunk is a tight group of classes, the interface can include several of the classes in the chunk.
Designing a clean interface and separating that interface from its implementation merely allows users to use the interface. But encapsulating (putting "in a capsule") the implementation forces users to use the interface.
Is Encapsulation a Security device?No.
Encapsulation != security.
Encapsulation prevents mistakes, not espionage.
What's the difference between the keywords struct and class?The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.
struct and class are otherwise functionally equivalent.
OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.
What is a reference? An alias (an alternate name) for an object.
References are frequently used for pass-by-reference:
void swap(int& i, int& j)
{
int tmp = i;
i = j;
j = tmp;
}
int main()
{
int x, y;
// ...
swap(x,y);
}
Here i and j are aliases for main's x and y respectively. In other words, i is x — not a pointer to x, nor a copy of x, but x itself. Anything you do to i gets done to x, and vice versa.
OK. That's how you should think of references as a programmer. Now, at the risk of confusing you by giving you a different perspective, here's how references are implemented. Underneath it all, a reference i to object x is typically the machine address of the object x. But when the programmer says i++, the compiler generates code that increments x. In particular, the address bits that the compiler uses to find x are not changed. A C programmer will think of this as if you used the C style pass-by-pointer, with the syntactic variant of (1) moving the & from the caller into the callee, and (2) eliminating the *s. In other words, a C programmer will think of i as a macro for (*p), where p is a pointer to x (e.g., the compiler automatically dereferences the underlying pointer; i++ is changed to (*p)++; i = 7 is automatically changed to *p = 7).
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object. It is not a pointer to the object, nor a copy of the object. It is the object.
What happens if you return a reference? The function call can appear on the left hand side of an assignment operator.
This ability may seem strange at first. For example, no one thinks the expression f() = 7 makes sense. Yet, if a is an object of class Array, most people think that a
= 7 makes sense even though a is really just a function call in disguise (it calls Array::operator[](int), which is the subscript operator for class Array).
class Array {
public:
int size() const;
float& operator[] (int index);
// ...
};
int main()
{
Array a;
for (int i = 0; i < a.size(); ++i)
a[i] = 7; // This line invokes Array::operator[](int)
}
When should I use references, and when should I use pointers?Use references when you can, and pointers when you have to.
References are usually preferred over pointers whenever you don't need "resetting". This usually means that references are most useful in a class's public interface. References typically appear on the skin of an object, and pointers on the inside.
The exception to the above is where a function's parameter or return value needs a "sentinel" reference. This is usually best done by returning/taking a pointer, and giving the NULL pointer this special significance (references should always alias objects, not a deference NULL pointer).
Note: Old line C programmers sometimes don't like references since they provide reference semantics that isn't explicit in the caller's code. After some C++ experience, however, one quickly realizes this is a form of information hiding, which is an asset rather than a liability. E.g., programmers should write code in the language of the problem rather than the language of the machine.
Is there any difference between List x; and List x();?A big difference!
Suppose that List is the name of some class. Then function f() declares a local List object called x:
void f()
{
List x; // Local object named x (of class List)
// ...
}
But function g() declares a function called x() that returns a List:
void g()
{
List x(); // Function named x (that returns a List)
// ...
}
How can I make a constructor call another constructor as a primitive?No way.
Dragons be here: if you call another constructor, the compiler initializes a temporary local object; it does not initialize this object. You can combine both constructors by using a default parameter, or you can share their common code in a private init() member function.
What is a destructors?A destructor gives an object its last rites.
Destructors are used to release any resources allocated by the object. E.g., class Lock might lock a semaphore, and the destructor will release that semaphore. The most common example is when the constructor uses new, and the destructor uses delete.
Destructors are a "prepare to die" member function. They are often abbreviated "dtor".
What's the order that local objects are destructed?In reverse order of construction: First constructed, last destructed.
In the following example, b's destructor will be executed first, then a's destructor:
void userCode()
{
Fred a;
Fred b;
// ...
}
What's the order that objects in an array are destructed?In reverse order of construction: First constructed, last destructed.
In the following example, the order for destructors will be a[9], a[8], ..., a[1], a[0]:
void userCode()
{
Fred a[10];
// ...
}
Can I overload the destructor for my class?No.
You can have only one destructor for a class Fred. It's always called Fred::~Fred(). It never takes any parameters, and it never returns anything.
You can't pass parameters to the destructor anyway, since you never explicitly call a destructor (well, almost never).
Should I explicitly call a destructor on a local variable?No!
The destructor will get called again at the close } of the block in which the local was created. This is a guarantee of the language; it happens automatically; there's no way to stop it from happening. But you can get really bad results from calling a destructor on the same object a second time! Bang! You're dead!
What is "self assignment"?Self assignment is when someone assigns an object with itself. For example,
#include "Fred.hpp" // Declares class Fred
void userCode(Fred& x)
{
x = x; // Self-assignment
}
Obviously no one ever explicitly does a self assignment like the above, but since more than one pointer or reference can point to the same object (aliasing), it is possible to have self assignment without knowning it:
#include "Fred.hpp" // Declares class Fred
void userCode(Fred& x, Fred& y)
{
x = y; // Could be self-assignment if &x == &y
}
int main()
{
Fred z;
userCode(z, z);
}
What is an operator overloading?It allows you to provide an intuitive interface to users of your class.
Operator overloading allows C/C++ operators to have user-defined meanings on user-defined types (classes). Overloaded operators are syntactic sugar for function calls:
class Fred {
public:
// ...
};
#if 0
// Without operator overloading:
Fred add(Fred, Fred);
Fred mul(Fred, Fred);
Fred f(Fred a, Fred b, Fred c)
{
return add(add(mul(a,b), mul(b,c)), mul(c,a)); // Yuk...
}
#else
// With operator overloading:
Fred operator+ (Fred, Fred);
Fred operator* (Fred, Fred);
Fred f(Fred a, Fred b, Fred c)
{
return a*b + b*c + c*a;
}
#endif
What are the benefits of operator overloading?By overloading standard operators on a class, you can exploit the intuition of the users of that class. This lets users program in the language of the problem domain rather than in the language of the machine.
The ultimate goal is to reduce both the learning curve and the defect rate.
What is a friend?Something to allow your class to grant access to another class or function.
Friends can be either functions or other classes. A class grants access privileges to its friends. Normally a developer has political and technical control over both the friend and member functions of a class (else you may need to get permission from the owner of the other pieces when you want to update your own class).
Do friends violate encapsulation?If they're used properly, they actually enhance encapsulation.
You often need to split a class in half when the two halves will have different numbers of instances or different lifetimes. In these cases, the two halves usually need direct access to each other (the two halves used to be in the same class, so you haven't increased the amount of code that needs direct access to a data structure; you've simply reshuffled the code into two classes instead of one). The safest way to implement this is to make the two halves friends of each other.
If you use friends like just described, you'll keep private things private. People who don't understand this often make naive efforts to avoid using friendship in situations like the above, and often they actually destroy encapsulation. They either use public data (grotesque!), or they make the data accessible between the halves via public get() and set() member functions. Having a public get() and set() member function for a private datum is OK only when the private datum "makes sense" from outside the class (from a user's perspective). In many cases, these get()/set() member functions are almost as bad as public data: they hide (only) the name of the private datum, but they don't hide the existence of the private datum.
Similarly, if you use friend functions as a syntactic variant of a class's public: access functions, they don't violate encapsulation any more than a member function violates encapsulation. In other words, a class's friends don't violate the encapsulation barrier: along with the class's member functions, they are the encapsulation barrier.
What are some advantages/disadvantages of using friend functions?They provide a degree of freedom in the interface design options.
Member functions and friend functions are equally privileged (100% vested). The major difference is that a friend function is called like f(x), while a member function is called like x.f(). Thus the ability to choose between member functions (x.f()) and friend functions (f(x)) allows a designer to select the syntax that is deemed most readable, which lowers maintenance costs.
The major disadvantage of friend functions is that they require an extra line of code when you want dynamic binding. To get the effect of a virtual friend, the friend function should call a hidden (usually protected:) virtual member function. This is called the Virtual Friend Function Idiom. For example:
class Base {
public:
friend void f(Base& b);
// ...
protected:
virtual void do_f();
// ...
};
inline void f(Base& b)
{
b.do_f();
}
class Derived : public Base {
public:
// ...
protected:
virtual void do_f(); // "Override" the behavior of f(Base& b)
// ...
};
void userCode(Base& b)
{
f(b);
}
The statement f(b) in userCode(Base&) will invoke b.do_f(), which is virtual. This means that Derived::do_f() will get control if b is actually a object of class Derived. Note that Derived overrides the behavior of the protected: virtual member function do_f(); it does not have its own variation of the friend function, f(Base&).
Should my class declare a member function or a friend function?Use a member when you can, and a friend when you have to.
Sometimes friends are syntactically better (e.g., in class Fred, friend functions allow the Fred parameter to be second, while members require it to be first). Another good use of friend functions are the binary infix arithmetic operators. E.g., aComplex + aComplex should be defined as a friend rather than a member if you want to allow aFloat + aComplex as well (member functions don't allow promotion of the left hand argument, since that would change the class of the object that is the recipient of the member function invocation).
In other cases, choose a member function over a friend function.
Does delete p delete the pointer p, or the pointed-to-data *p?The pointed-to-data.
The keyword should really be delete_the_thing_pointed_to_by. The same abuse of English occurs when freeing the memory pointed to by a pointer in C: free(p) really means free_the_stuff_pointed_to_by(p).
Can I free() pointers allocated with new? Can I delete pointers allocated with malloc()?No!
It is perfectly legal, moral, and wholesome to use malloc() and delete in the same program, or to use new and free() in the same program. But it is illegal, immoral, and despicable to call free() with a pointer allocated via new, or to call delete on a pointer allocated via malloc().
Beware! I occasionally get e-mail from people telling me that it works OK for them on machine X and compiler Y. That does not make it right! Sometimes people say, "But I'm just working with an array of char." Nonetheless do not mix malloc() and delete on the same pointer, or new and free() on the same pointer! If you allocated via p = new char[n], you must use delete[] p; you must not use free(p). Or if you allocated via p = malloc(n), you must use free(p); you must not use delete[] p or delete p! Mixing these up could cause a catastrophic failure at runtime if the code was ported to a new machine, a new compiler, or even a new version of the same compiler.
You have been warned.
Can I use realloc() on pointers allocated via new?No!
When realloc() has to copy the allocation, it uses a bitwise copy operation, which will tear many C++ objects to shreds. C++ objects should be allowed to copy themselves. They use their own copy constructor or assignment operator.
Besides all that, the heap that new uses may not be the same as the heap that malloc() and realloc() use!
Do I need to check for NULL before delete p?No!
The C++ language guarantees that delete p will do nothing if p is equal to NULL. Since you might get the test backwards, and since most testing methodologies force you to explicitly test every branch point, you should not put in the redundant if test.
Wrong:
if (p != NULL)
delete p;
Right:
delete p;