const members and static members
Cont members of class
const data members
Const data members can only be initialized through a constructor initializer list.
class Box {<!-- --> private: const int length; //Length const int width; //width const int height; //height public: Box(); Box(int H, int W, int L); }; Box::Box(int H, int W, int L) : height{<!-- --> H }, width{<!-- --> W }, length{<!-- --> L } {<!-- -->} Box::Box() : height{<!-- --> 1 }, width{<!-- --> 2 }, length{<!-- --> 3 } {<!-- --> }
Const data members can set initial values within the class.
class Box {<!-- --> private: const int length = 3; //Length const int width = 4; //Width const int height = 5; //Height public: Box() = default; Box(int H, int W, int L); }; Box::Box(int H, int W, int L) : height{<!-- --> H }, width{<!-- --> W }, length{<!-- --> L } {<!-- -->}
const member function
By adding the const keyword after the parameter list of a function, a member function that uses const is called a const member function.
Const member functions can only reference data members in this class, but cannot modify them.
class Box {<!-- --> private: const int length; //Length const int width; //width const int height; //height public: Box() = default; Box(int H, int W, int L); void Print(void) const; //Declaration, print length, width, height }; Box::Box(int H, int W, int L) : height{<!-- --> H }, width{<!-- --> W }, length{<!-- --> L } {<!-- -->} void Box::Print(void) const //The definition is also modified with const {<!-- --> cout << length << ' ' << width << ' ' << height << endl; }
Const member functions can be called by both const and non-const objects, while non-const member functions can only be called by non-const objects.
If a const member function returns *this
as a reference, its return type will be a constant reference.
class Box {<!-- --> private: int length; //Length int width; //width int height; //height public: Box() = default; Box(int H, int W, int L); const Box & amp; Print(void) const; //return constant reference }; Box::Box(int H, int W, int L) : height{<!-- --> H }, width{<!-- --> W }, length{<!-- --> L } {<!-- -->} const Box & amp; Box::Print(void) const //Return constant reference {<!-- --> cout << length << ' ' << width << ' ' << height << endl; return *this; }
Constructors cannot be declared const.
mutable data members
If you want to modify the data member through a const member function, you can declare the data member as mutable.
class Box {<!-- --> private: int length; //Length int width; //width mutable int height; //Height, declared as mutable public: Box() = default; Box(int H, int W, int L); int Volume(int h) const; //Modify the height of the box and find the volume }; Box::Box(int H, int W, int L) : height{<!-- --> H }, width{<!-- --> W }, length{<!-- --> L } {<!-- -->} int Box::Volume(int h) const //Modify the height of the box and find the volume {<!-- --> height = h; //Box height can be modified return length * width * height; }
const object
When defining an object, you can add the keyword const to specify the object as a const object.
A const object must have an initial value, and all data members in the object cannot be modified.
A const object can only call its const member functions (except for destruction and construction). Const member functions are the only external interface of const objects.
Const member functions can access data members in const objects, but they are still not allowed to modify the values of data members in const objects.
const Box B1; //Call parameterless constructor const Box B2{<!-- -->1,2,3}; //Call parameterized constructor B1.Print(); //Call const member function B1.Volume(10); //mutable data members can be modified
Aggregation class
An aggregate class allows users to directly access its members and has a special initialization syntax.
We say a class is aggregated when it satisfies the following conditions:
- All members are public.
- No constructor is defined.
- There is no in-class initializer.
- There is no base class and no virtual functions.
Literal constant class
An aggregate class whose data members are all literal types is a literal constant class.
A class is a literal constant class if it is not an aggregate class but meets the following requirements:
- Data members must be literal types.
- A class must have at least one constexpr constructor.
- If a data member contains an in-class initializer, the initializer for the built-in type member must be a constant expression; or if the member is of a class type, the initializer must use the member’s own constexpr constructor.
- Classes must use the default definition of a destructor.
constexpr constructor
Although the constructor cannot be const, the constructor of a literal constant class can be a constexpr function.
The constexpr constructor must initialize all data members. The initial value is either the constexpr constructor or a constant expression.
The constexpr constructor is used to generate constexpr objects and the parameters or return types of constexpr functions.
A literal constant class
class Birthday {<!-- --> private: unsigned int year = 0; //year unsigned int month = 0; //month unsigned int day =0; //day public: constexpr Birthday() = default; constexpr Birthday(unsigned int y, unsigned int m, unsigned int d); //constexpr constructor void Print(void) const; }; constexpr Birthday::Birthday(unsigned int y, unsigned int m, unsigned int d) : year{<!-- --> y }, month{<!-- --> m }, day{<!-- --> d } {<!-- -->} void Birthday::Print(void) const {<!-- --> cout << year << "Year" << month << "Month" << day<< "Day" << endl; }
constexpr object
A constexpr object can only call its constexpr member functions.
Constexpr objects can only be generated by calling the constructor.
constexpr Birthday b{<!-- --> 2012,3,12 }; b.Print();
Static members
Static data members
Variables that are part of a class but not part of a class object are called static members.
Static data members cannot be initialized using constructors and can only be initialized outside the class.
When initializing static data members outside a class, the static keyword cannot be repeated.
class Box {<!-- --> private: int length; //length int width; //width int height; //height static int number; //Count the number of boxes public: Box(); Box(int H, int W, int L); }; int Box::number = 0; //Initialize static data members outside the class
Const static data members can specify initial values within the class.
However, static data members must be const of integral or enumeration type, or constexpr of literal type, and the initializer must be a constant-expression.
class Box {<!-- --> private: int length; //Length int width; //width int height; //height const static int number = 0; //const static data member public: Box(); Box(int H, int W, int L); };
Static data members are allocated space when the program starts and are released when the program ends.
All objects of this class share one or more static data members.
Static member function
Similarly, functions that require access to class members without being called through a specific object are called static member functions.
Static member functions are not bound to any object, have no this pointer, and cannot access non-static members of this class.
Static member functions cannot be declared const.
class Box {<!-- --> private: int length; //Length int width; //width int height; //height static int number; //Count the number of boxes public: Box(); Box(int H, int W, int L); static int GetNumber(void); //static member function }; int Box::number = 0; Box::Box(int H, int W, int L) : height{<!-- --> H }, width{<!-- --> W }, length{<!-- --> L } {<!-- --> number + = 1; //Every time a box is created, number increases by one } Box::Box() : height{<!-- --> 1 }, width{<!-- --> 2 }, length{<!-- --> 3 } {<!-- --> number + = 1; //Every time a box is created, number increases by one } int Box::GetNumber(void) //static member function {<!-- --> return number; }
No object is defined, and static members can also be referenced through class names.
cout << Box::GetNumber() << endl; //No object generated, number = 0;
Although static members do not belong to an object of the class, we can still use objects, references or pointers of the class to access static members.
int main() {<!-- --> Box B1; Box B2{<!-- --> 1,1,1}; cout << B2.GetNumber() << endl; //Two objects are generated, number = 2; return 0; }
When defining static members outside a class, the static keyword cannot be repeated.