C++ summary of frequently asked interview questions

  • 2020-05-19 05:24:33
  • OfStack

This article summarizes the C++ interview FAQ. I will share it with you for your reference as follows:

1. Inheritance

The access level of the public parent class remains the same
The public members of the protected parent class program protected in the derived class, and the rest remains unchanged
All members of the private parent class become private


#include <iostream>
using namespace std;
class base
{
  public:
    void printa()
    { cout <<"base"<< endl; }
  protected:
    void printhello()
    { cout <<"helo"<< endl; }
  private:
    void printnohello()
    { cout <<"no hello"<< endl; }
};
class derived : public base
{
  public:
    void printb() { printhello(); }
    // void printc() { printnohello(); } //printnohello Is a private function of the parent class and is not accessible 
};
int main()
{
  base a;
  a.printa();
  //a.printhello(); //printhello Is the class derived the protected Function, not accessible. 
}

2. Differences between sizeof and strlen

sizeof is an operator, strlen is a library function.
The parameters of sizeof can be data types or variables, while strlen can only take parameters with a string ending '\ 0'.
The compiler calculated the sizeof result at compile time. The strlen function must be evaluated at run time. And while sizeof calculates the size of the data type in memory, strlen calculates the actual length of the string.
Array to do sizeof parameters do not degenerate, pass to strlen will degenerate into a pointer.


#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main()
{
  int a[] = {1, 2, 3, 4, 5};
  cout << sizeof(a) << endl; //20
//  cout << strlen(a) << endl;
  char b[] = {'a', 'b'};
  cout << strlen(b) << endl; //6
  cout << sizeof(b) << endl; //2
}

3. What is the difference between malloc in C and new in C++

new, delete are operators that can be overridden and can only be used in C++.
malloc and free are functions that can be overridden, and C and C++ can be used.
new can call the constructor of the object, and the corresponding delete can call the corresponding destructor.
malloc only allocates memory, free only reclaims memory, and does not perform constructs and destructors
new and delete return Pointers of some data type, malloc and free return Pointers of void.

Note: the memory space requested by malloc should be freed by free, while the memory space requested by new should be freed by delete. Do not mix them.

Because the mechanisms are different.

4.1. c/static c + +

To understand static, you must first understand the other keyword, auto. In fact, the variables we usually declare without the modification of static are all of auto, because it is the default. The meaning of auto is that the program automatically controls the life cycle of a variable. It usually means that a variable is allocated when it enters its scope and released when it leaves its scope. While static is not auto, variables are allocated at the initialization of the program and are not released until the program exits. That is, static allocates freed variables according to the life cycle of the program, not the life cycle of the variable itself; So, an example like this:


void func()
{
  int a;
  static int b;
}

Every time this function is called, the variable a is new, because it is allocated when entering the function body and released when exiting the function body. Therefore, multiple threads calling this function will have their own independent variable a, because it will always be redistributed. And variable b, whether you use this function in the program initialization it is assigned by the time, or in the first time I performed to its statement distribution (different compilers may be different), so the function called multiple threads, always visit with a variable b, this is also must pay attention to in the multithreaded programming!

Full usage of static:

1. Static member of class:


class A
{
  private:
    static int s_value;
};

It must be initialized in cpp:


int A::s_value = 0; //  Notice, it's not there static The modified! 

The static member of the class is a common member of all instances of the class. In other words, it is a global variable within the scope of the class. It can also be understood as a global variable named A::s_value. It's very simple, because it's allocated at initialization time, so it's allocated once, so it's Shared;

The static member of the class must be initialized, and the reason is the same as 1, because it is allocated at the initialization time of the program, so there must be initialization, the class is only declared, in cpp is the initialization, you can put a breakpoint on the initialization code, before the program executes the first statement of main will go there; If your static member is a class, its constructor will be called.

2. Class static function:


class A
{
  private:
  static void func(int value);
};

The implementation does not require the modification of static because static is a declarative keyword; The static function of the class is a global function in the category of the class, can not access the private members of the class, can only access the static members of the class, do not need an instance of the class can be called; In effect, it is a global function that adds access to the class: void A::fun(int);

Static member functions can inherit and override, but cannot be virtual functions.

3. Global variables that are only valid in cpp:

Declare in the global scope of the cpp file:


static int g_value = 0;

This variable means that it is valid within cpp, but cannot be accessed by other cpp files. If there are two cpp files that declare global static variables with the same name, they are actually two independent variables;

If you do not declare global variables using static:


int g_value = 0;

There is no guarantee that this variable will not be Shared by other cpp, nor that 1 will be Shared by other cpp, because to share a global variable with multiple cpp, it should be declared as extern (external); It is also possible that the compiler will report that variables have been repeatedly defined. In general, it is not recommended to write this way, and it is not clear how to use this global variable.

If you declare in a header file:


static int g_vaule = 0;

One global variable will be created for each cpp containing the header file, but they are all independent; It is not recommended to write it this way. It is not clear how to use this variable, because it only creates a set of variables with the same name and different scope.

By the way, here is how to declare all cpp shareable global variables, declared as extern in the header file:


extern int g_value; //  Be careful not to initialize the values! 

It is then initialized (once) in any one of the cpp containing the header file:


#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main()
{
  int a[] = {1, 2, 3, 4, 5};
  cout << sizeof(a) << endl; //20
//  cout << strlen(a) << endl;
  char b[] = {'a', 'b'};
  cout << strlen(b) << endl; //6
  cout << sizeof(b) << endl; //2
}

0

Then all the cpp files containing the header can access the same variable with the name g_value;

4.2 what is the use of static in C

(1) hidden. When we compile multiple files at the same time, all global variables and functions without the prefix static are globally visible, so we use static to define functions and variables with the same name in different files without worrying about naming conflicts.
Keep the content of the variables persistent. Variables stored in static data areas are initialized as soon as the program begins to run, which is only one initialization. There are two types of variables stored in static storage: global variables and static variables.
(3) is initialized to 0 by default. In fact, global variables also have this 1 property, because global variables are also stored in the static data area. In static data areas, the default value of all bytes in memory is 0×00, which in some cases can reduce the programmer's workload.

5. Briefly describe the memory allocation of C\C++ program compilation

There are three kinds of memory allocation methods in C and C++ :

(1) allocation from static storage area: the built-in program has been allocated at compile time, and the built-in program exists for the entire running period. It's fast, it's not easy to make a mistake, because there's a system to fix it. For example, global variables, static variables and so on.
(2) allocation on the stack: when the function is executed, the storage units of local variables in the function are created on the stack, and these storage units are automatically released at the end of the function execution. Stack memory allocation operations are built into the processor's instruction set, which is very efficient, but the allocated memory capacity is limited.
(3) allocation from the heap: that is, dynamic memory allocation. The program requests any size of memory with malloc or new while it is running, and the programmer is responsible for releasing the memory with free or delete at any time. The lifetime of dynamic memory is up to the programmer and it is very flexible to use. If space is allocated on the heap, it is the responsibility to reclaim it, otherwise the running program will have a memory leak, and frequent allocation and release of heap space of different sizes will result in in-heap fragmentation.

One C, C++ program compilation memory is divided into five storage areas: the heap area, the stack area, the global area, the text constant area, the program code area.

6. Three characteristics of object orientation

(1) encapsulation, that is to encapsulate the objective things into abstract classes, and the class can put their own data and methods to only allow trusted classes or objects to operate, to the untrusted information hiding.
Inheritance refers to the ability to use all the functions of an existing class and extend them without having to rewrite the original class. New classes created by inheritance are called "subclasses" or "derived classes." The process of inheritance is the process from 1 to special. Inheritance can be implemented through "inheritance" and "composition".
(3) polymorphic, in simple terms, is 1 sentence: allows the subclass type to assign a pointer to the superclass type pointer. Implement polymorphic, there are 2 ways, override, overload.

Overrides are subclasses that redefine the virtual functions of their superclasses.
Overloading means allowing multiple functions of the same name to exist with different parameter lists (perhaps different number of arguments, perhaps different types of arguments, perhaps both).

Summary: role

Encapsulation can hide the implementation details, making the code modular
(2) inheritance can extend the existing code module (class); They're all about -- code reuse
(3) polymorphism is to achieve another purpose - interface reuse! The purpose of polymorphism is to ensure that a class is properly called when it inherits and derives from an instance of any class in the family tree.

7. Briefly describe the realization principle of polymorphism

The compiler finds a virtual function in a class and immediately generates the virtual function table vtable for that class. Each table entry of the virtual function table is a pointer to the corresponding virtual function. The compiler also implicitly inserts a pointer vptr to the table of virtual functions into this class. When the constructor of this class is called, the compiler implicitly executes the vptr and vtable association code in the constructor of the class, pointing vptr to the corresponding vtable, and associating the class with the vtable of this class. In addition, when calling the constructor of the class, the pointer to the base class has now become the this pointer to the concrete class, so you can get the correct vtable by relying on this this pointer.

In this way, it can be truly connected to the body of the function, which is the basic principle of dynamic linkage and polymorphic realization.

Note: 1 must distinguish between virtual functions, pure virtual functions, and virtual inheritance. Keep in mind the principle of virtual function implementation, because polymorphic C++ is one of the most important test points in the interview, and virtual functions are the basis of polymorphic implementation.

8. Member functions of c++ empty class

The default constructor
The default copy constructor
The default assignment operator
The default destructor
The default addressing operator
The default addressing operator is const

Note: the compiler defines these functions only when they are actually used.

9. Tell me about your knowledge of copy constructors and assignment operators

Two differences:

Copy the constructor to generate a new class object, and the assignment operator cannot.
Since the copy constructor directly constructs a new class object, it is not necessary to verify whether the source object is the same as the new object before initializing the object. The assignment operator requires this operation, and in addition, if there is a memory allocation in the original object in the assignment operation, the memory should be freed first.

Note: when there are member variables with pointer types in a class, 1 must override the copy constructor and assignment operator, not the default.

10. Use C++ to design a class that cannot be inherited


#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main()
{
  int a[] = {1, 2, 3, 4, 5};
  cout << sizeof(a) << endl; //20
//  cout << strlen(a) << endl;
  char b[] = {'a', 'b'};
  cout << strlen(b) << endl; //6
  cout << sizeof(b) << endl; //2
}

1

The flow object in C++ USES this principle. Prevents assignment and replication.

Overrides, overrides, and hidden differences between class members

There are several major differences between overrides and overloads

The difference between the scope: the overridden and overridden functions are in two classes, while the overloaded and overloaded functions are in the same class.
Parameter difference: the overwritten function and the overwritten function's parameter list 1 must be the same, while the overloaded function and the overloaded function's parameter list 1 must be different.
The difference between virtual: an overridden function in an overridden base class must have an virtual modifier, whereas an overloaded function or an overridden function can be modified by virtual or not.

There are several differences between hiding and overwriting and overloading

(1) different from the overloading range: and overwrite 1, hidden functions and hidden functions are not in the same class
Parameter difference: the hidden function and the hidden function parameter list can be the same, also can be different, but the function name must be the same. When the arguments are different, the functions of the base class are hidden, not overwritten, regardless of whether the arguments in the base class are modified by virtual or not

Description: although both overloading and overloading are the basis of polymorphic implementation, they are completely different in technology and purpose. Overloading is the polymorphism of dynamic binding, while overloading is the polymorphism of static binding.

12. What is the use of extern

The variable or function identified by extern declares its definition in a different file, prompting the compiler to look for its definition in another module when it encounters this variable or function.

13. The difference between a reference and a pointer

The reference must be initialized, but no storage space is allocated. Pointers do not have to be initialized at declaration time, and storage space needs to be allocated at initialization time
The reference cannot be changed after initialization. The pointer can change the object
There is no reference to a null value, but there is a pointer to a null value

14. Array pointer


#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main()
{
  int a[] = {1, 2, 3, 4, 5};
  cout << sizeof(a) << endl; //20
//  cout << strlen(a) << endl;
  char b[] = {'a', 'b'};
  cout << strlen(b) << endl; //6
  cout << sizeof(b) << endl; //2
}

2

15. const int *a and int * const a


int main()
{
  int b = 3;
  int c = 4;
  const int *p = &b;  // Is equivalent to  int const *p = &b;
  p = &c;        // Modifier value, pointer variable 
              //*p = 5;//error  Modifies the value, which is immutable 
  cout << *p << endl;
  int a = 5;
  int * const q = &a;   // Modify a pointer 
              //p = &c;//error Modifies pointer, pointer immutable 
  *p = 5;        // Modifies pointer with variable value 
}

I hope this article is helpful to you C++ programming.


Related articles: