Learning to be Giant.

C++ Learning Notes IV


Too many things to do this week and too tired today. Only make up for things that should be done yesterday.

More about Classes

  1. Delegating Constructors

     class Class{
         Class(int a, double b, char c){}
         Class():Class(1,2.0,'c'){} // this is a delegating constructor
  2. Implicit class-type conversion

    Every constructor that can be called with a single argument defines an implicit conversion to a class type.

     class Class {
         Class(std::string str){}
     void func(Class c) {}
     // omitted some codes
     func(string("test")); // legal, since the string is converted to Class

    NOTICE: conversion can only be performed once. For example:

     func("test"); // this is illegal, since "test" is converted to string first
  3. Prevent implicit class-type conversion To prevent the conversion, one can put an explicit before the definition of the constructor.

     explicit Class(std::string str){}

    NOTICE: explicit constructors can be used only for direct initialization. For example:

     Class c("test"); // ok
     Class c = "test"; // error

    static_cast is viable.

     Class c = static_cast<Class>("test");
  4. Aggregate Classes An aggregate class is a class:
    • all the data members are public
    • it does not define any constructors
    • it has no in-class initializers
    • it has no base classes or virtual functions

    For example:

     struct Data {
         int val;
         string s;

    An aggregate class can be initialized like:

     Data d = {0, "hello"};

    The initialization list should have the order exactly the same with the declaration order of the members in the class.

  5. Literal classes An aggregate class with all data members are literal types is a literal class. If it’s not a aggregate class, it should satisfy:

    • The data members all must have literal type.
    • The class must have at least one constexpr constructor.
    • If a data member has an in-class initializer, the initializer for a member of built-in type must be a constant expression, or if the member has class type, the initializer must use the member’s own constexpr constructor.
    • The class must use default definition for its destructor, which is the member that destroys objects of the class type.

    A constexpr constructor is a constructor with body empty.

    1. constructor cannot have return statement
    2. the only executable statement of constexpr is return
    3. constructors cannot be const
  6. static data members

    a static data member can have the same type as the class type of which it is a member. A nonstatic data member is restricted to being declared as a pointer or a reference to an object of its class

     class Bar {
         static Bar mem1; //ok
         Bar *mem2; //ok
         Bar mem3; //error

IO classes

IO objects cannot be copied or assigned.

ofstream out1, out2;
out1 = out2; // error: cannot assign stream objects 
ofstream print(ofstream); // error:can’t initialize the ofstream parameter 
out2 = print(out2); // error: cannot copy stream objects

Disclaimer: This is a personal weblog. The opinions expressed here represent my own and not those of any entity with which I have been, am now, or will be affiliated.