10 Most Asked Questions About C++
Tags: cpp
Published: 2020-10-23 07:50:55

C++ is a general-purpose high-level programming language developed as an extension of C language. It is a cross-platform programming language used to create high-performance applications. And, here we have prepared a list of the most commonly asked questions about C++.

## 10 Most Asked Questions About C++

### 1. What is the “–>” operator in C+ array?

**Answer:**

`-->` is not an operator. It is in fact two separate operators, `--` and `>`.

The conditional’s code decrements `x`, while returning `x`‘s original (not decremented) value, and then compares the original value with 0 using the `>` operator.

To better understand, the statement could be written as follows:

```
while( (x--) > 0 )
```

**Alternative Answer:**

For something completely different… `x` slides to `0`.

```
while (x --\
            \
             \
              \
               > 0)
     printf("%d ", x);
```

### 2. What are the differences between a pointer variable and a reference variable in C++?

**Answer:**

A pointer can be re-assigned: `int x = 5; int y = 6; int *p; p = &x; p = &y; *p = 10; assert(x == 5); assert(y == 10);` . A reference cannot, and must be assigned at initialization: `int x = 5; int y = 6; int &r = x;`.

A pointer has its own memory address and size on the stack (4 bytes on x86), whereas a reference shares the same memory address (with the original variable) but also takes up some space on the stack. Since a reference has the same address as the original variable itself, it is safe to think of a reference as another name for the same variable.

Note: What a pointer points to can be on the stack or heap. But this doesn’t mean that a pointer must point to the stack. A pointer is just a variable that holds a memory address. This variable is on the stack. Since a reference has its own space on the stack, and since the address is the same as the variable it references. This implies that there is a real address of a reference that the compiler will not tell you. `int x = 0; int &r = x; int *p = &x; int *p2 = &r; assert(p == p2);`

You can have pointers to pointers to pointers offering extra levels of indirection. Whereas references only offer one level of indirection. `int x = 0; int y = 0; int *p = &x; int *q = &y; int **pp = &p; pp = &q;//*pp = q **pp = 4; assert(y == 4); assert(x == 0);`.

A pointer can be assigned `nullptr` directly, whereas reference cannot. If you try hard enough, and you know how, you can make the address of a reference `nullptr`. Likewise, if you try hard enough, you can have a reference to a pointer, and then that reference can contain `nullptr`. `int *p = nullptr; int &r = nullptr; <--- compiling error int &r = *p; <--- likely no compiling error, especially if the nullptr is hidden behind a function call, yet it refers to a non-existent int at address 0`.

Pointers can iterate over an array; you can use `++` to go to the next item that a pointer is pointing to, and `+ 4` to go to the 5th element. This is no matter what size the object is that the pointer points to.

A pointer needs to be de-referenced with `*` to access the memory location it points to, whereas a reference can be used directly. A pointer to a class/struct uses `->` to access it’s members whereas a reference uses a ..

References cannot be stuffed into an array, whereas pointers can be.

Const references can be bound to temporaries. Pointers cannot (not without some indirection): `const int &x = int(12); //legal C++ int *y = &int(12); //illegal to dereference a temporary`. This makes const& safer for use in argument lists and so forth.

### 3. How to iterate over the words of a string?

**Answer:**

For what it’s worth, here’s a way to extract tokens from an input string, relying only on standard library facilities. It’s an example of the power and elegance behind the design of the STL.

```
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>

int main() {
    using namespace std;
    string sentence = "And I feel fine...";
    istringstream iss(sentence);
    copy(istream_iterator<string>(iss),
         istream_iterator<string>(),
         ostream_iterator<string>(cout, "\n"));
}
```

Instead of copying the extracted tokens to an output stream, one could insert them into a container, using the same generic <a href="https://en.cppreference.com/w/cpp/algorithm/copy">`copy`</a> algorithm.

```
vector<string> tokens;
copy(istream_iterator<string>(iss),
     istream_iterator<string>(),
     back_inserter(tokens));
```

or create the `vector` directly:

```
vector<string> tokens{istream_iterator<string>{iss},
```

**Alternative Answer:**

Use this to split string by a delimiter. First put the results in a pre-constructed vector, the second returns a new vector.

```
#include <string>
#include <sstream>
#include <vector>
#include <iterator>

template <typename Out>
void split(const std::string &s, char delim, Out result) {
    std::istringstream iss(s);
    std::string item;
    while (std::getline(iss, item, delim)) {
        *result++ = item;
    }
}

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, std::back_inserter(elems));
    return elems;
}
```

Note that this solution does not skip empty tokens, so the following will find 4 items, one of which is empty:

```
std::vector<std::string> x = split("one:two::three", ':');
```

### 4. What does the explicit keyword mean?

**Answer:**

The compiler is allowed to make one implicit conversion to resolve the parameters to a function. What this means is that the compiler can use constructors callable with a **single parameter** to convert from one type to another in order to get the right type for a parameter.

Here’s an example class with a constructor that can be used for implicit conversions:

```
class Foo
{
public:
  // single parameter constructor, can be used as an implicit conversion
  Foo (int foo) : m_foo (foo) 
  {
  }

  int GetFoo () { return m_foo; }

private:
  int m_foo;
};
```

Here’s a simple function that takes a `Foo` object:

```
void DoBar (Foo foo)
{
  int i = foo.GetFoo ();
}
```

and here’s where the `DoBar` function is called.

```
int main ()
{
  DoBar (42);
}
```

The argument is not a `Foo` object, but an `int`. However, there exists a constructor for `Foo` that takes an `int` so this constructor can be used to convert the parameter to the correct type.

The compiler is allowed to do this once for each parameter.

Prefixing the `explicit` keyword to the constructor prevents the compiler from using that constructor for implicit conversions. Adding it to the above class will create a compiler error at the function call `DoBar (42)`. It is now necessary to call for conversion explicitly with `DoBar (Foo (42))`

The reason you might want to do this is to avoid accidental construction that can hide bugs. Contrived example:

- You have a `MyString(int size)` class with a constructor that constructs a string of the given size. You have a function `print(const MyString&)`, and you call `print(3)` (when you actually intended to call `print("3")`). You expect it to print “3”, but it prints an empty string of length 3 instead.

**Alternative Answer:**

Suppose, you have a class `String`:

```
class String {
public:
    String(int n); // allocate n bytes to the String object
    String(const char *p); // initializes object with char *p
};
```

Now, if you try:

```
String mystring = 'x';
```

The character `'x'` will be implicitly converted to `int` and then the `String(int)` constructor will be called. But, this is not what the user might have intended. So, to prevent such conditions, we shall define the constructor as `explicit`:

```
class String {
public:
    explicit String (int n); //allocate n bytes
    String(const char *p); // initialize sobject with string p
};
```

### 5. Why is “using namespace std;” considered bad practice?

**Answer:**

This is not related to performance at all. But consider this: you are using two libraries called Foo and Bar:

```
using namespace foo;
using namespace bar;
```

Everything works fine, and you can call `Blah()` from Foo and `Quux()` from Bar without problems. But one day you upgrade to a new version of Foo 2.0, which now offers a function called `Quux()`. Now you’ve got a conflict: Both Foo 2.0 and Bar import `Quux()` into your global namespace. This is going to take some effort to fix, especially if the function parameters happen to match.

If you had used `foo::Blah()` and `bar::Quux()`, then the introduction of foo::Quux() would have been a non-event.

### 6. How do you set, clear, and toggle a single bit?

**Answer:**

**Setting a bit**

Use the bitwise OR operator (|) to set a bit.

```
number |= 1UL << n;
```

That will set the `n`th bit of `number`. `n` should be zero, if you want to set the 1st bit and so on upto `n-1`, if you want to set the `n`th bit.

Use `1ULL` if `number` is wider than `unsigned long;` promotion of `1UL << n` doesn’t happen until after evaluating `1UL << n` where it’s undefined behaviour to shift by more than the width of a `long`. The same applies to all the rest of the examples.

**Clearing a bit**

Use the bitwise AND operator (&) to clear a bit.

```
number &= ~(1UL << n);
```

That will clear the `n`th bit of `number`. You must invert the bit string with the bitwise NOT operator (~), then AND it.

**Toggling a bit**

The XOR operator (^) can be used to toggle a bit.

```
number ^= 1UL << n;
```

That will toggle the `n`th bit of `number`.

**Checking a bit**

To check a bit, shift the number n to the right, then bitwise AND it:

```
bit = (number >> n) & 1U;
```

That will put the value of the `n`th bit of `number` into the variable `bit`.

**Changing the nth bit to x**

Setting the `n`th bit to either `1` or `0` can be achieved with the following on a 2’s complement C++ implementation:

```
number ^= (-x ^ number) & (1UL << n);
```

Bit `n` will be set if `x` is `1`, and cleared if `x` is `0`. If `x` has some other value, you get garbage. `x = !!x` will booleanize it to 0 or 1.

To make this independent of 2’s complement negation behaviour (where `-1` has all bits set, unlike on a 1’s complement or sign/magnitude C++ implementation), use unsigned negation.

```
number ^= (-(unsigned long)x ^ number) & (1UL << n);
```

or

```
unsigned long newbit = !!x;    // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
```

It’s generally a good idea to use unsigned types for portable bit manipulation.

or

```
number = (number & ~(1UL << n)) | (x << n);
```

`(number & ~(1UL << n))` will clear the `n`th bit and `(x << n)` will set the `n`th bit to `x`.

It’s also generally a good idea not to copy/paste code in general and so many people use preprocessor macros or some sort of encapsulation.

**Alternative Answer:**

Using the Standard C++ Library: <a href="https://en.cppreference.com/w/cpp/utility/bitset">`std::bitset<N>`</a>.

Or the <a href="https://en.wikipedia.org/wiki/Boost_%28C%2B%2B_libraries%29">Boost</a> version: <a href="https://www.boost.org/doc/libs/1_74_0/libs/dynamic_bitset/dynamic_bitset.html">boost::dynamic_bitset</a>.

There is no need to roll your own:

```
#include <bitset>
#include <iostream>

int main()
{
    std::bitset<5> x;

    x[1] = 1;
    x[2] = 0;
    // Note x[0-4]  valid

    std::cout << x << std::endl;
}
```

```
[Alpha:] > ./a.out
00010
```

The Boost version allows a runtime sized bitset compared with a <a href="https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library">standard library</a> compile-time sized bitset.

### 7. When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?

**Answer:**

`static_cast` is the first cast you should attempt to use. It does things like implicit conversions between types (such as `int` to `float` or pointer to `void*`), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating `static_cast` isn’t necessary, but it’s important to note that the `T(something)` syntax is equivalent to `(T)something` and should be avoided (more on that later). A `T(something, something_else)` is safe, however, and guaranteed to call the constructor.

`static_cast` can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn’t cast through `virtual` inheritance. It does not do checking, however, and it is undefined behavior to `static_cast` down a hierarchy to a type that isn’t actually the type of the object.

`const_cast` can be used to remove or add `const` to a variable; no other C++ cast is capable of removing it (not even `reinterpret_cast`). It is important to note that modifying a formerly `const` value is only undefined if the original variable is `const;` if you use it to take the `const` off a reference to something that wasn’t declared with `const`, it is safe. This can be useful when overloading member functions based on `const`, for instance. It can also be used to add const to an object, such as to call a member function overload.

`const_cast` also works similarly on `volatile`, though that’s less common.

`dynamic_cast` is exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards – you can cast sideways or even up another chain. The `dynamic_cast` will seek out the desired object and return it if possible. If it can’t, it will return `nullptr` in the case of a pointer, or throw `std::bad_cast` in the case of a reference.

`dynamic_cast` has some limitations, though. It doesn’t work if there are multiple objects of the same type in the inheritance hierarchy (the so-called ‘dreaded diamond’) and you aren’t using `virtual` inheritance. It also can only go through public inheritance – it will always fail to travel through `protected` or `private` inheritance. This is rarely an issue, however, as such forms of inheritance are rare.

`reinterpret_cast` is the most dangerous cast, and should be used very sparingly. It turns one type directly into another — such as casting the value from one pointer to another, or storing a pointer in an `int`, or all sorts of other nasty things.

Largely, the only guarantee you get with reinterpret_cast is that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions that reinterpret_cast cannot do, too. It’s used primarily for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data or storing data in the low bits of a pointer to aligned data.

**C-style cast** and **function-style** cast are casts using `(type)object or type(object),` respectively, and are functionally equivalent. They are defined as the first of the following which succeeds:

- `const_cast`
- `static_cast` (though ignoring access restrictions)
- `static_cast` (see above), then `const_cast`
- `reinterpret_cast`
- `reinterpret_cast`, then `const_cast`

It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a `reinterpret_cast`, and the latter should be preferred when explicit casting is needed, unless you are sure `static_cast` will succeed or `reinterpret_cast` will fail. Even then, consider the longer, more explicit option.

C-style casts also ignore access control when performing a `static_cast`, which means that they have the ability to perform an operation that no other cast can. This is mostly a kludge, though, and is just another reason to avoid C-style casts.

**Additional Answer:**

Use `dynamic_cast` for converting pointers/references within an inheritance hierarchy.

Use `static_cast` for ordinary type conversions.

Use `reinterpret_cast` for low-level reinterpreting of bit patterns. Use with extreme caution.

Use `const_cast` for casting away `const/volatile`. Avoid this unless you are stuck using a const-incorrect API.

### 8. What is the difference between #include <filename> and #include “filename”?

**Answer:**

In practice, the difference is in the location where the preprocessor searches for the included file.

For `#include <filename>`, the preprocessor searches in an implementation-dependent manner, normally in search directories pre-designated by the compiler/IDE. This method is normally used to include standard library header files.

For `#include "filename"`, the preprocessor searches first in the same directory as the file containing the directive and then follows the search path used for the `#include <filename>` form. This method is normally used to include programmer-defined header files.

### 9. Why is reading lines from stdin much slower in C++ than Python?

**Answer:**

By default, `cin` is synchronized with stdio, which causes it to avoid any input buffering. If you add this to the top of your main, you should see much better performance:

```
std::ios_base::sync_with_stdio(false);
```

Normally, when an input stream is buffered, instead of reading one character at a time, the stream will be read in larger chunks. This reduces the number of system calls, which are typically relatively expensive. However, since the `FILE*` based `stdio` and `iostreams` often have separate implementations and therefore separate buffers, this could lead to a problem if both were used together. For example:

```
int myvalue1;
cin >> myvalue1;
int myvalue2;
scanf("%d",&myvalue2);
```

If more input was read by `cin` than it actually needed, then the second integer value wouldn’t be available for the `scanf` function, which has its own independent buffer. This would lead to unexpected results.

To avoid this, by default, streams are synchronized with `stdio`. One common way to achieve this is to have `cin` read each character one at a time as needed using `stdio` functions. Unfortunately, this introduces a lot of overhead. For small amounts of input, this isn’t a big problem, but when you are reading millions of lines, the performance penalty is significant.

Fortunately, the library designers decided that you should also be able to disable this feature to get improved performance if you knew what you were doing, so they provided the <a href="https://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio">`sync_with_stdio` method</a>.

**Alternative Answer:**

You can also use <a href="https://en.wikipedia.org/wiki/Strace">dtruss/strace</a> on each test.

C++

```
./a.out < in
Saw 6512403 lines in 8 seconds.  Crunch speed: 814050
```

syscalls `sudo dtruss -c ./a.out < in`

```
CALL                                        COUNT
__mac_syscall                                   1
<snip>
open                                            6
pread                                           8
mprotect                                       17
mmap                                           22
stat64                                         30
read_nocancel                               25958
```

Python

```
./a.py < in
Read 6512402 lines in 1 seconds. LPS: 6512402
```

syscalls `sudo dtruss -c ./a.py < in`

```
CALL                                        COUNT
__mac_syscall                                   1
<snip>
open                                            5
pread                                           8
mprotect                                       17
mmap                                           21
stat64                                         29
```

### 10. Why can templates only be implemented in the header file?

**Answer:**

It is not necessary to put the implementation in the header file, see the alternative solution at the end of this answer.

Anyway, the reason your code is failing is that, when instantiating a template, the compiler creates a new class with the given template argument. For example:

```
template<typename T>
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f; 
```

When reading this line, the compiler will create a new class (let’s call it `FooInt`), which is equivalent to the following:

```
struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}
```

Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int). If these implementations were not in the header, they wouldn’t be accessible, and therefore the compiler wouldn’t be able to instantiate the template.

A common solution to this is to write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.

Foo.h

```
template <typename T>
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"
```

Foo.tpp

```
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}
```

This way, implementation is still separated from declaration, but is accessible to the compiler.

**Alternative Answer:**

Another solution is to keep the implementation separated, and explicitly instantiate all the template instances you’ll need:

Foo.h

```
// no implementation
template <typename T> struct Foo { ... };
```

Foo.cpp

```
// implementation of Foo's methods

// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float
```

**In Conclusion**

These are the top 10 most commonly asked questions about C++. If you have any suggestions or any confusion, please comment below. If you need any help, we will be glad to help you.

We, at <a href="https://www.truemark.dev/hire/resources/">Truemark</a>, provide services like web and mobile app development, digital marketing, and website development. So, if you need any help and want to work with us, please feel free to contact us.

Hope this article helped you.

This post was first published on <a href="https://thedevpost.com/blog/10-most-asked-questions-about-cplusplus//">DevPostbyTruemark</a>.