Header Ads Widget

Ticker

6/recent/ticker-posts

20+ Amazing C++ tricks that every programmer should know

C++ Tips and Tricks

Not at all like other item arranged programming dialects, C++, by a wide margin, is the most complicated and amazing. The code design can frequently be peculiar and tangled. Intriguingly, this precarious part causes C++ software engineers to remain alert, now and again even to the purpose in confusing a prepared developer. There is quite often space for calibrating the code on each return to. Numerous developers who compose code in different dialects as an expert prerequisite love fiddling with C/C++, because of its unusual and freak style. The article will manage some not really clear tips that frequently may have been ignored or need reviving.
 
 
  1. Use header guards to prevent multiple inclusions of header files.
c++
#ifndef MYHEADER_H #define MYHEADER_H // code goes here #endif // MYHEADER_H
  1. Always initialize your variables to avoid undefined behavior.
c++
int x = 0; // initialization
  1. Use const whenever possible to prevent accidental modification of values.
c++
const int MAX_SIZE = 10;
  1. Use references to avoid unnecessary copying of objects.
c++
void foo(const std::string& str) { // code goes here }
  1. Use range-based for loops to iterate over collections.
c++
std::vector<int> vec = {1, 2, 3}; for (const auto& elem : vec) { // code goes here }
  1. Use std::unique_ptr to manage memory and avoid memory leaks.
c++
std::unique_ptr<int> ptr = std::make_unique<int>(42);
  1. Use constexpr to evaluate expressions at compile-time.
c++
constexpr int add(int x, int y) { return x + y; }
  1. Use auto to let the compiler deduce the type of a variable.
c++
auto x = 42; // x is an int
  1. Use lambda expressions for simple function objects.
c++
std::vector<int> vec = {1, 2, 3}; std::for_each(vec.begin(), vec.end(), [](int x) { std::cout << x << std::endl; });
  1. Use std::array for fixed-size arrays.
c++
std::array<int, 3> arr = {1, 2, 3};
  1. Use std::vector for dynamic arrays.
c++
std::vector<int> vec = {1, 2, 3};
  1. Use std::map for key-value pairs.
c++
std::map<std::string, int> map = {{"foo", 42}, {"bar", 13}};
  1. Use std::unordered_map for fast lookups.
c++
std::unordered_map<std::string, int> map = {{"foo", 42}, {"bar", 13}};
  1. Use static_cast to convert between related types.
c++
double x = 3.14; int y = static_cast<int>(x);
  1. Use dynamic_cast for runtime type checking.
c++
class Base { virtual void foo() {} }; class Derived : public Base {}; Base* ptr = new Derived; if (auto derived_ptr = dynamic_cast<Derived*>(ptr)) { // ptr is a Derived* }
  1. Use const_cast to remove const-ness.
c++
const int x = 42; int& y = const_cast<int&>(x);
  1. Use noexcept to indicate functions that do not throw exceptions.
c++
void foo() noexcept { // code goes here }
  1. Use the ternary operator for simple conditionals.
c++
int x = 42; int y = (x > 0) ? 1 : -1;
  1. Use the auto keyword for function return type deduction.
c++
auto foo(int x) { if (x > 0) { return "positive"; } else { return "negative"; } }
  1. Use std::move to transfer ownership of an object.
c++
std::vector

 


1. Literals and Variables

A strict, ordinarily, is an undeniable worth of a particular kind controlled by its structure. The kind of the strict can be int, unsigned int, long, unsigned long, long or unsigned long as indicated by the size of the worth from littlest to biggest, individually. There is no short exacting. For instance,

23 is a decimal exacting, of course marked

023 is an octal strict. Since it is prefixed by 0 (zero), can be marked or unsigned

0x23 or 0X23 is a hexadecimal exacting. Since it is prefixed by 0x or 0X, can be marked or unsigned

Gliding point literals can be composed as 1.2345f or utilizing logical (outstanding) documentation 1.2345E0 or 1.2345e0

'A' will be a person exacting and

"Some text" is a string strict

There are additions (u/U - unsigned, l/L-long or long twofold, ll/LL long, f/F-twofold) for numeric literals and prefixes (u – 16-cycle unicode character, U - 32-bit unicode character, L-wide person, u8 – utf-8 string literals) for character literals to supersede the significance. Some legitimate literals are as per the following:
 
L'A', u8"some text", 23E-10, 1.2324L, 78ULL
 
Presently, shouldn't something be said about - 23? - 23 is anything but an exacting fundamentally, however the '- ' (short sign) is an administrator that invalidates the decimal strict 23.

Factors are named memory area where the size involved is characterized by the sort related. There are two kinds of qualities consistently connected with a variable: lvalue (memory area) and rvalue (read esteem). This is the fundamental explanation factors are addressable and exacting constants are not, and we can compose,

  1. // iv has both lvalue and rvalue associated
  2. // with the name.
  3. int iv=5;
  4. // cannot be written, because it is a literal
  5. // constant.
  6. 5=iv; or 6=5;

But, what happens when we write:
  1. iv = iv + 5;
Here, the variable at the left hand side is referred to have lvalue and the same variable at the right side of '=' operator refers the rvalue. So, the rvalue of the variable +  literal, 5, is stored in the memory location named iv.

2. Initialization and Assignment

There is an unpretentious distinction among instatement and task. Instatement alludes to a worth given to a variable at the hour of its creation and task alludes to the rvalue of a variable that is overwritten with another worth. For instance,
 
 
  1. // it is an initialization. It is a good programming
  2. // practice to initialize a variable as soon as it is
  3. // created.
  4. int i=0;
  5. // it is an assignment where initial value is
  6. // overwritten with a new one.
  7. i=10;
In C++ , a variable can be initialized in one of many ways, such as

  1. int i={0};
  2. int i{0};
  3. int i(0);

3. The Tricky const Qualifier

The const qualifier has one reason: to make the article unchangeable or consistent. That implies a consistent must be introduced and never allocated in C++. As ought to be self-evident, the introduction should be done on creation. For instance,
  1. const double area=35.78f;
Now, suppose we declare a pointer that that holds the lvalue of an area:
  1. // error! Pointer to a variable.
  2. double *ptr_area=&area;
This is an erroneous statement because we had declared the area as a constant but left a room for assignment.
  1. // error! Trying to change the constant value
  2. ptr_area=6.56;
Thus, if we want to declare a pointer to point to a constant, we must declare a pointer that addresses a constant object, as follows.
  1. // OK, pointer to a constant object
  2. const double *ptr_area=&area;
Can a pointer to a constant object refer to a variable (not constant)? Certainly.
  1. double area=35.78f;
  2. const double *ptr_area=&area; // OK
  3. rea=11.56f; // OK
  4. *ptr_area=9.62f // error!
A pointer to a consistent article can allude to a non-steady factor yet no task is permitted through the pointer.

In every one of the first cases, a pronounced pointer is a pointer to a consistent article. Imagine a scenario in which we need to make a pointer that is itself a steady. In like case, say,

  1. double area=35.78f;
  2. double another_area=98.34f;
  3. // OK during initialization
  4. double *const ptr_area=&area;
  5. *ptr_area=77.56f; //OK
This is because the pointer is constant but the variable it points to is not a constant.
  1. //error! Assignment not allowed.
  2. ptr_area=&another_area;
So, it's pretty obvious from all the previous statements, we can easily understand the following code:
  1. const double area=35.78f;
  2. const double *const pointer_area=&area;
Thus, it is a constant pointer to a constant area.

4. Validity Assertion

Affirmations prove to be useful in really looking at the legitimacy of an articulation. This should be possible with the assistance of the state full scale characterized in the <cassert> header record. This is especially helpful as a troubleshooting apparatus to test whether a variable has a right worth. In the event that the worth of the articulation is 0 (bogus), a blunder message is printed, and afterward calls a cut short capacity to end program execution. For instance, assume a variable, say maxsize, ought to never be more noteworthy than 1024 in a program. We can utilize statement to test the worth and print a blunder message in case it's erroneous.
  1. #include<cassert>
  2. int main()
  3. {
  4. assert(maxsize<=1024);
  5. }
In the event that the worth is more prominent than 1024, a blunder message with the line number and document name is imprinted in the standard yield prior to ending the program. As it was said, it is useful in troubleshooting, however in the event that when we would prefer not to investigate or incapacitate affirmation, we can embed the accompanying line as the principal line of the source code:

#define NDEBUG



5. String Conversions

String change to a whole number or the other way around is a typical marvel of ordinary programming. C++ 11 presented some advantageous coverings for the reason. For instance, to change a whole number over to a string, we might compose the accompanying:
  1. #include<string>
  2. int main()
  3. {
  4. int ival=112233;
  5. string str=to_string(ival);
  6. return 0;
  7. }
To convert a string to an integer, we may write the code as follows:
  1. #include<string>
  2. int main()
  3. {
  4. string num_str="112233";
  5. int ival=stoi(num_str);
  6. long long llval=stoll(num_str);
  7. return 0;
  8. }

Conclusion

The most grounded segment should have the most grounded base. At the point when one goes up the stepping stool of programming, these five ideas are extremely significant. Go ahead and remark on what other calculated regions you as a developer regularly return to, relearn, or rehash.

Post a Comment

0 Comments