Explain the sizeof and typeid operators in C++ programming

  • 2020-05-07 20:10:33
  • OfStack

sizeof operator
produces an operand size that is related to the size of the char type.
grammar


sizeof unary-expression sizeof ( type-name )

note
The result of the sizeof operator is of type size_t, which is the integer type defined in the STDDEF.H containing file. With this operator, you can avoid specifying computer-dependent data sizes in your program.
The operands of sizeof can be 1 of the following:
Type name. To use sizeof for a type name, the name must be enclosed in parentheses.
One expression. When used for expressions, sizeof can be specified with or without parentheses. The expression is not evaluated.
When the sizeof operator is applied to an object of type char, it generates 1. When the sizeof operator is applied to an array, it produces the total number of bytes in that array, not the size of the pointer represented by the array identifier. To get the size of a pointer represented by an array identifier, pass it as an argument to a function using sizeof. Such as:


#include <iostream>
using namespace std;

size_t getPtrSize( char *ptr )
{
  return sizeof( ptr );
}

int main()
{
  char szHello[] = "Hello, world!";

  cout << "The size of a char is: "
     << sizeof( char )
     << "\nThe length of " << szHello << " is: "
     << sizeof szHello
     << "\nThe size of the pointer is "
     << getPtrSize( szHello ) << endl;
}

Sample output


The size of a char is: 1
The length of Hello, world! is: 14
The size of the pointer is 4

When the sizeof operator is applied to an class, struct, or union type, the result is the number of bytes in the object of that type and any padding added to align the member data on the word boundary. The result does not correspond to the size calculated by adding up the storage requirements of each member. The /Zp compiler options and pack miscellaneous affect the alignment boundaries of members.
The sizeof operator never produces a 0, even for empty classes.
The sizeof operator cannot be used for the following operands:
Function. (however, sizeof can be applied to Pointers to functions.)
A domain.
Undefined class.
void type.
Dynamically allocated array.
External array.
Incomplete type.
Name of an incomplete type with braces.
When the sizeof operator is applied to the reference, the result is the same as when sizeof is applied to the object itself.
If an unsized array is the last element of the structure, the sizeof operator returns the size of the structure without the array.
The sizeof operator is commonly used to evaluate the number of elements in an array by using the following form of an expression:
sizeof array / sizeof array[0]

typeid operator
grammar


   typeid( 
   type-id
    )
typeid( expression )
( expression )

note
The typeid operator allows you to determine the type of an object at run time.
The result of typeid is const type_info&. The value is a reference to an type_info object of type type-id or expression, depending on the form of typeid used.
The typeid operator does not apply to managed types (abstract declarators or instances).
The typeid operator performs a runtime check when applied to the lvalue of a polymorphic class type, where the actual type of the object cannot be determined by the static information provided. Such cases are:
A reference to a class
Pointer to dereference with *
Pointer with lower index (i.e. []). (note that it is generally not safe to use subscripts with Pointers to polymorphic types.)
If expression points to a base class type, but the object is actually a type derived from that base class, the type_info reference of the derived class is the result. expression must point to polymorphic types (classes with virtual functions). Otherwise, the result is type_info of the static class referenced in expression. In addition, the pointer must be dereferenced to use the object it points to. If the pointer is not dereferred, the result will be the type_info of the pointer, not what it points to. Such as:


// expre_typeid_Operator.cpp
// compile with: /GR /EHsc
#include <iostream>
#include <typeinfo.h>

class Base {
public:
  virtual void vvfunc() {}
};

class Derived : public Base {};

using namespace std;
int main() {
  Derived* pd = new Derived;
  Base* pb = pd;
  cout << typeid( pb ).name() << endl;  //prints "class Base *"
  cout << typeid( *pb ).name() << endl;  //prints "class Derived"
  cout << typeid( pd ).name() << endl;  //prints "class Derived *"
  cout << typeid( *pd ).name() << endl;  //prints "class Derived"
  delete pd;
}

If expression is de-referencing a pointer and the value of the pointer is zero, typeid throws an bad_typeid exception. If the pointer does not point to a valid object, the s 112en_rtti_object exception is thrown to indicate that an RTTI that tried to analyze an error (such as an access conflict) is invalid in some way (invalid pointer or code not compiled with /GR).
If expression is neither a pointer nor a reference to the base class of the object, the result is a statically typed type_info reference representing expression. The static type of the expression will reference the type of the expression known at compile time. When evaluating the static type of an expression, the execution semantics are ignored. In addition, references are ignored (if possible) when determining the static type of an expression:


// expre_typeid_Operator_2.cpp
#include <typeinfo>

int main()
{
  typeid(int) == typeid(int&); // evaluates to true
}
typeid  Can also be used in templates to determine the type of template parameter: 
// expre_typeid_Operator_3.cpp
// compile with: /c
#include <typeinfo>
template < typename T > 
T max( T arg1, T arg2 ) {
  cout << typeid( T ).name() << "s compared." << endl;
  return ( arg1 > arg2 ? arg1 : arg2 );
}


Related articles: