Effective C + + learning notes 03

Keywords: C++

03: use const as much as possible

1:const modification of pointers and constants

char greeting[]="Hello";
char* p=greeting;                      //non-const pointer, non-const data
cons seven char* p=greeting;           //non-const pointer, const data
char* coast p=greeting;            //const pointer, non-const data
coast char* coast p=greeting;   // const pointer, const data

2:const modification of iterators

STL iterators are modeled based on pointers, so iterators act like T * pointers

std::vector<int> vec;
...
const std::vector<int>::iterator iter = vec.begin();  //iter acts like a T* const
*iter=10;                                             //No problem, change what iter refers to
++iter;//Wrong! iter yes
std::vector<int>::const_iterator cIter = vec.begin();//cIter acts like a const T*
*cIter=10; //Wrong* cIter is const
++cIter;//No problem, change cItero

3: Making the function return a constant value can often reduce the accidents caused by customer errors without giving up security and efficiency.

operator * declarative:

class Rational{...};
const Rational operator* (const Rational& lhs, const Rational& rhs);

Rational a, b, c;
...

If the returned object is not const, the following is true:

(a*b)=c;  //Call the operator on the result of a*b=

This is why operator * returns a const object.

4: const member function

1) Two member functions can be overloaded if they are only different in constancy.

void print(const TextBlock& ctb)     //ctb in this function is const
{
    std::cout<<ctb[0];               //Call const TextBlock::operator []
    ...
}

2) Note that the return type of non const operator [] is reference to char, not char. If opera [] only returns a char, the following sentences cannot be compiled:

tb[0]='x';

That's because if the return type of a function is a built-in type, it's never legal to change the return value of a function.

3) Bitwise consistency (also known as physical consistency)

People in the bitwise const camp believe that member functions can be called const only if they do not change any member variables of the object (except static). That is, it does not change any bit in the object.
However, there may be cases that do not comply with bitwise consistency, but can be compiled as follows:

class CTextBlock{
public:
    char& operator[](std::size t position) const             //bitwise const declaration
    {return pText[position];}                                //But it's not appropriate

private:
    char* pText;
};
const CTextBlock cctb("Hello");      //Declare a constant object.
char* pc=&cctb[0];                   //Call const operator [] to get a pointer
                                     //Data pointing to cctb.
*pc='J';                             //cctb now has content like "Jello".

4)logical constness

This group advocates that a const member function can modify some bits in the object it processes, but only if the client cannot detect it.
To change a member variable in the const member function, you need to prefix the variable name with mutable.

class CTextBlock {
public:
    ...
    std::size t length()const;
private:
    char* pText;
    mutable std::size_t textLength;  //These member variables may always
    mutable bool lengthIsValid;      //Will be changed, even in
};                                   //const member function.
std::size_t CTextBlock::length() const
{
    if(!lengthIsValid){
          textLength=std::strlen(pText); //Now, you can
          lengthIsValid=true;            //You can do the same.
      }
    return textLength;
}

5: Avoid repetition in const and non const member functions

Const and non const member functions have solutions to code duplication.
There are the following examples:

class TextBlock {
public:
    ...
const char& operator[](std::size one position) const
{
      ...             //Boundaries checking
      ...             //Log access data
      ...             //verify data integrity
      return text[position];
}
char& operator[](std::size t position)
{
      ...              //Boundaries checking
      ...              //Log access data
      ...              //verify data integrity
      return text[position];
}
private:
    std::string text;
};

The solutions are as follows:;

class TextBlock {
public:
const char& operator[](std::sizese t position) const //as always
{
    ...
    ...
    ...
    return text[position];
}
char& operator[] (std::size_ t position) //Now just call const op []
{
return
  const cast<char&>(                              //Divide const of op [] return value
      static_cast<const TextBlock&>(*this)       //Add const to * this
           [position]                             //Call const op []
    );
}
...
}

Note: const can be called by non const, but non const cannot be called by const.

Summary:
1: Declaring something as const helps the compiler detect incorrect usage. Const can be applied to objects, function parameters, function return types, member function bodies in any scope.
2: The compiler enforces bitwise constness, but you should use "conceptual constancy" when writing programs
(conceptualconstness).
3: When const and non const member functions have substantially equivalent implementations, making the non const version call the const version can avoid code duplication.

.

Posted by Cereals on Sun, 10 Oct 2021 05:41:47 -0700