There are 6 versions of C++ language namely C++98, C++03, C++11, C++14, C++17, and C++20.
There are only two standard libraries in C++ language namely old C library (libc.lib) and new C++ library (libcp.lib).
Standard Libraries: Standard C++ consists of three important parts −
The core language giving all the building blocks including variables, data types and literals, etc.
The C++ Standard Library giving a rich set of functions manipulating files, strings, etc.
The Standard Template Library (STL) giving a rich set of methods manipulating data structures, etc.
C++ is statically types. i.e C++ programming language is said to use static typing when type checking is performed during compile-time as opposed to run-time.
C++ fully supports object-oriented programming, including the four pillars of object-oriented development −
Encapsulation
Data hiding
Inheritance
Polymorphism
https://www.tutorialspoint.com/cplusplus/cpp_interview_questions.htm
what is the use of mutable storage class specifier? example program?
what is difference between shallow copy and deep copy? example program?
what is diamond inheritance problem? how to resolve it? example program?
example programs for static member variables and static member functions?
what is the use of default standard streams cerr and clog?
example program for friend class and friend functions?
why is size of empty class ia 1 byte?
Which function is used to move the stream pointer for the purpose of reading data from stream? seekg()
Which function is used to move the stream pointer for the purpose of writing data from stream? seekp()
can destructor be overloaded?
No. it can not be overloaded as only form is without the parameters.
what is this pointer?
this, is a pointer variable of the compiler which always holds the current active object's address.
what is scope resolution operator (::)?
scope resolution operator (::) is used to
resolve the scope of global variables
to associate function definition to a class if the function is defined outside the class.
what is a namespace?
namespace is the logical division of the code which can be used to resolve the name conflict of the identifiers by placing them in different namespace.
how can we catch all kind of exceptions in a single catch block?
the catch block with ellipses(...) as follows:
catch(...)
{
}
https://www.toptal.com/c-plus-plus/interview-questions
What will the line of code below print out and why?
#include <iostream>
int main(int argc, char **argv)
{
std::cout << 25u - 50;
return 0;
}
The answer is not -25. Rather, the answer (which will surprise many) is 4294967271, assuming 32 bit integers. Why?
In C++, if the types of two operands differ from one another, then the operand with the “lower type” will be promoted to the type of the “higher type” operand, using the following type hierarchy (listed here from highest type to lowest type): long double, double, float, unsigned long int, long int, unsigned int, int (lowest).
So when the two operands are, as in our example, 25u (unsigned int) and 50 (int), the 50 is promoted to also being an unsigned integer (i.e., 50u).
Moreover, the result of the operation will be of the type of the operands. Therefore, the result of 25u - 50u will itself be an unsigned integer as well. So the result of -25 converts to 4294967271 when promoted to being an unsigned integer.
What is the error in the code below and how should it be corrected?
my_struct_t *bar;
/* ... do stuff, including setting bar to point to a defined my_struct_t object ... */
memset(bar, 0, sizeof(bar));
The last argument to memset should be sizeof(*bar), not sizeof(bar). sizeof(bar) calculates the size of bar (i.e., the pointer itself) rather than the size of the structure pointed to by bar.
The code can therefore be corrected by using sizeof(*bar) as the last argument in the call to memset.
A sharp candidate might point out that using *bar will cause a dereferencing error if bar has not been assigned. Therefore an even safer solution would be to use sizeof(my_struct_t). However, an even sharper candidate must know that in this case using *bar is absolutely safe within the call to sizeof, even if bar has not been initialized yet, since sizeof is a compile time construct.
what is the use of memset() ?
Assuming buf is a valid pointer, what is the problem in the code below? What would be an alternate way of implementing this that would avoid the problem?
size_t sz = buf->size();
while ( --sz >= 0 )
{
/* do something */
}
The problem in the above code is that --sz >= 0 will always be true so you’ll never exit the while loop (so you’ll probably end up corrupting memory or causing some sort of memory violation or having some other program failure, depending on what you’re doing inside the loop).
The reasons that --sz >= 0 will always be true is that the type of sz is size_t. size_t is really just an alias to one of the fundamental unsigned integer types. Therefore, since sz is unsigned, it can never be less than zero (so the condition can never be true).
One example of an alternative implementation that would avoid this problem would be to instead use a for loop as follows:
for (size_t i = 0; i < sz; i++)
{
/* do something */
}
Consider the two code snippets below for printing a vector. Is there any advantage of one vs. the other? Explain.
Option 1:
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); itr++) {
itr->print();
}
Option 2:
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
itr->print();
}
Although both options will accomplish precisely the same thing, the second option is better from a performance standpoint. This is because the post-increment operator (i.e., itr++) is more expensive than pre-increment operator (i.e., ++itr). The underlying implementation of the post-increment operator makes a copy of the element before incrementing it and then returns the copy.
That said, many compilers will automatically optimize the first option by converting it into the second.
what is use of vector in c++?
Is it possible to have a recursive inline function?
Although you can call an inline function from within itself, the compiler may not generate inline code since the compiler cannot determine the depth of recursion at compile time. A compiler with a good optimizer can inline recursive calls till some depth fixed at compile-time (say three or five recursive calls), and insert non-recursive calls at compile time for cases when the actual depth gets exceeded at run time.
C++ supports multiple inheritance. What is the “diamond problem” that can occur with multiple inheritance? Give an example.
It means that we cannot create hybrid inheritance using multiple and hierarchical inheritance.
Let’s consider a simple example. A university has people who are affiliated with it. Some are students, some are faculty members, some are administrators, and so on. So a simple inheritance scheme might have different types of people in different roles, all of whom inherit from one common “Person” class. The Person class could define an abstract getRole() method which would then be overridden by its subclasses to return the correct role type.
But now what happens if we want to model the role of a Teaching Assistant (TA)? Typically, a TA is both a grad student and a faculty member. This yields the classic diamond problem of multiple inheritance and the resulting ambiguity regarding the TA’s getRole() method:
(Note the diamond shape of the above inheritance diagram, hence the name.)
Which getRole() implementation should the TA inherit? That of the Faculty Member or that of the Grad Student? The simple answer might be to have the TA class override the getRole() method and return newly-defined role called “TA”. But that answer is also imperfect as it would hide the fact that a TA is, in fact, both a faculty member and a grad student.
Explain the volatile and mutable keywords.
Hide answer
The volatile keyword informs the compiler that a variable may change without the compiler knowing it. Variables that are declared as volatile will not be cached by the compiler, and will thus always be read from memory.
The mutable keyword can be used for class member variables. Mutable variables are allowed to change from within const member functions of the class.
Are you allowed to have a static const member function? Explain your answer.
A const member function is one which isn’t allowed to modify the members of the object for which it is called. A static member function is one which can’t be called for a specific object.
Thus, the const modifier for a static member function is meaningless, because there is no object associated with the call.
A more detailed explanation of this reason comes from the C programming language. In C, there were no classes and member functions, so all functions were global. A member function call is translated to a global function call. Consider a member function like this:
void foo(int i);
A call like this:
obj.foo(10);
…is translated to this:
foo(&obj, 10);
This means that the member function foo has a hidden first argument of type T*:
void foo(T* const this, int i);
If a member function is const, this is of type const T* const this:
void foo(const T* const this, int i);
Static member functions don’t have such a hidden argument, so there is no this pointer to be const or not.
What is a storage class?
Hide answer
A class that specifies the life and scope of its variables and functions is called a storage class.
In C++ following the storage classes are supported: auto, static, register, extern, and mutable.
Note, however, that the keyword register was deprecated in C++11. In C++17, it was removed and reserved for future use.
How can a C function be called in a C++ program?
Using an extern "C" declaration:
//C code
void func(int i)
{
//code
}
void print(int i)
{
//code
}
//C++ code
extern "C"{
void func(int i);
void print(int i);
}
void myfunc(int i)
{
func(i);
print(i);
}