由于自己的博客挂了,临时借用 rabbyte 爷的博客发布一下。

勘误

使用 fstream 读写二进制文件,只能对 POD Object 操作,内含 std::string 的对象无法正常操作!

  • 构造函数和析构函数的调用顺序

ISO/IEC 14882:1998

Initialization (of bases and members) shall proceed in the following order:

  • First, and only for the constructor of the most derived class as described below, virtual base classes shall be initialized in the order they appear on a depth-first left-to-right traversal...
  • Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
  • Then, nonstatic data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
  • Finally, the body of the constructor is executed.
#include <iostream>

class Base {
public:
  Base(int id_) : id(id_) {
    std::cout << "CTOR of Base [" << id << "] called" << std::endl;
  }
  ~Base() {
    std::cout << "DTOR of Base [" << id << "] called" << std::endl; 
  }

private:
  int id;
};

class Derived : public Base {
public:
  Derived(int id_) : base6(6), Base(0), id(id_), base5(5) {
    std::cout << "CTOR of Derived [" << id << "] called" << std::endl;
  }
  ~Derived() {
    std::cout << "DTOR of Derived [" << id << "] called" << std::endl;
  }

private:
  int id;
  Base base5;
  Base base6;
};

Base base1(1);
Derived derived2(2);

int main() {

  return 0;
}
  • 静态数据成员和成员函数
#include <iostream>

class Employee {
public:
  Employee(int id_) : id(id_) {
    std::cout << "CTOR of Employee [" << id << "] called" << std::endl;
    count++;
  }
  ~Employee() {
    std::cout << "DTOR of Employee [" << id << "] called" << std::endl;
    count--;
  }
  static void increment_id(Employee& e) {
    e.id++;
  }
  void increment_id() {
    id++;
  }
  static int get_count() {
    return count;
  }

private:
  int id;
  static int count;
};

int Employee::count = 0;

void print_count() {
  std::cout << "Count: " << Employee::get_count() << std::endl;
}

int main() {
  auto e1 = new Employee(1);
  print_count();
  auto e2 = new Employee(2);
  print_count();
  delete e2;
  print_count();
  delete e1;
  print_count();

  return 0;
}
  • 对象数组和对象指针数组
#include <iostream>

class Student {
public:
  Student(int id_) : id(id_) {
    std::cout << "CTOR of Student [" << id << "] called" << std::endl;
  }
  Student() : Student(-1) {}
  ~Student() {
    std::cout << "DTOR of Student [" << id << "] called" << std::endl;
  }

private:
  int id;
};

int main() {
  Student* students_obj_array = new Student[5];
  Student** students_ptr_array = new Student*[5];
  for (int i = 0; i < 5; ++i) {
    students_ptr_array[i] = new Student(i);
  }

  delete[] students_obj_array;
  for (int i = 0; i < 5; ++i) {
    delete students_ptr_array[i];
  }
  delete[] students_ptr_array;

  return 0;
}
  • 运算符重载
#include <iostream>

const std::size_t MAX_BUFFER_SIZE = 1024;

class String {
public:
  explicit String(const char* str_) : length(strlen(str_)) {
    str = new char[length + 1];
    for (std::size_t i = 0; i < length; i++) {
      str[i] = str_[i];
    }
    str[length] = '\0';
  }
  String() : length(0) {
    str = new char[1];
    str[0] = '\0';
  }
  String(const String& rhs) : String(rhs.str) {}
  ~String() {
    delete[] str;
  }
  String& operator=(const String& rhs) {
    if (this == &rhs) return *this;
    length = rhs.length;
    delete[] str;
    str = new char[length + 1];
    for (std::size_t i = 0; i < length; i++) {
      str[i] = rhs.str[i];
    }
    str[length] = '\0';
    return *this;
  }
  String& operator=(const char* rhs) {
    length = strlen(rhs);
    delete[] str;
    str = new char[length + 1];
    for (std::size_t i = 0; i < length; i++) {
      str[i] = rhs[i];
    }
    str[length] = '\0';
    return *this;
  }
  String operator+(const String& rhs) const {
    String res;
    res.length = length + rhs.length;
    delete[] res.str;
    res.str = new char[res.length + 1];
    for (std::size_t i = 0; i < length; i++) {
      res.str[i] = str[i];
    }
    for (std::size_t i = 0; i < rhs.length; i++) {
      res.str[length + i] = rhs.str[i];
    }
    res.str[res.length] = '\0';
    return res;
  }
  String operator+(const char* rhs) const {
    String res;
    res.length = length + strlen(rhs);
    delete[] res.str;
    res.str = new char[res.length + 1];
    for (std::size_t i = 0; i < length; i++) {
      res.str[i] = str[i];
    }
    for (std::size_t i = 0; i < res.length - length; i++) {
      res.str[length + i] = rhs[i];
    }
    res.str[res.length] = '\0';
    return res;
  }
  friend std::istream& operator>>(std::istream& is, String& rhs);
  friend std::ostream& operator<<(std::ostream& os, const String& rhs);
  friend String operator+(const char* str, const String& rhs);
  bool operator<(const String& rhs) {
    std::size_t min_length = std::min(length, rhs.length);
    for (std::size_t i = 0; i < min_length; i++) {
      if (str[i] != rhs.str[i]) {
        return str[i] < rhs.str[i];
      }
    }
    return length < rhs.length;
  }
  String operator*(std::uint32_t times) {
    String res;
    for (std::uint32_t i = 0; i < times; i++) {
      res = res + *this;
    }
    return res;
  }

private:
  std::size_t length;
  char* str;
};

std::istream& operator>>(std::istream& is, String& rhs) {
  char str[MAX_BUFFER_SIZE];
  is >> str;
  rhs = str;
  return is;
}

std::ostream& operator<<(std::ostream& os, const String& rhs) {
  os << rhs.str;
  return os;
}

String operator+(const char* str, const String& rhs) {
  String lhs(str);
  return lhs + rhs;
}

int main() {
  String s1, s2;
  std::cin >> s1 >> s2;
  std::cout << "Operator +: [" + s1 + s2 + "]" << std::endl;
  std::cout << "Operator <: [" << (s1 < s2) << "]" << std::endl;
  std::cout << "Operator *: [" << s1 * 5 << "]" << std::endl;
  
  return 0;
}
  • 临时对象
#include <iostream>

class Number {
public:
  Number(int value_) : value(value_) {
    std::cout << "CTOR of Number [" << value << "] called" << std::endl;
  }
  Number(const Number& rhs) : value(rhs.value) {
    std::cout << "Copy CTOR of Number [" << value << "] called" << std::endl;
  }
  Number(Number &&rhs) : value(rhs.value) {
    std::cout << "Move CTOR of Number [" << value << "] called" << std::endl;
  }
  ~Number() {
    std::cout << "DTOR of Number [" << value << "] called" << std::endl;
  }

private:
  int value;
};

void foo(const Number& num) {
  std::cout << "Function foo() called" << std::endl;
}

void bar(Number num) {
  std::cout << "Function bar() called" << std::endl;
}

Number gee() {
  Number tmp(5);
  return tmp;
}

int main() {
  std::cout << "Start calling function foo()" << std::endl;
  foo(1);
  std::cout << "Finished calling function foo()" << std::endl;

  Number num2(2);
  std::cout << "Start calling function foo()" << std::endl;
  foo(num2);
  std::cout << "Finished calling function foo()" << std::endl;

  std::cout << "Start calling function bar()" << std::endl;
  bar(3);
  std::cout << "Finished calling function bar()" << std::endl;

  Number num4(4);
  std::cout << "Start calling function bar()" << std::endl;
  bar(num4);
  std::cout << "Finished calling function bar()" << std::endl;

  Number num5 = gee();

  return 0;
}
  • 二进制文件读写
#include <iostream>
#include <fstream>
#include <string>

class foo {
  friend std::ostream& operator<<(std::ostream& os, const foo& f);
  friend std::istream& operator>>(std::istream& is, foo& f);

private:
  int a, b;
  std::string s;

public:
  foo(int a_, int b_, std::string s_) : a(a_), b(b_), s(std::move(s_)) {}
  foo() = default;
};

std::ostream& operator<<(std::ostream& os, const foo& f) {
  os << f.a << " " << f.b << " " << f.s;
  return os;
}

std::istream& operator>>(std::istream& is, foo& f) {
  is >> f.a >> f.b >> f.s;
  return is;
}

int main() {
  std::ofstream ostrm("out.dat", std::ios::binary | std::ios::out);
  foo f(2, 3, "ddd");
  foo g(4, 5, "eee");
  ostrm.write(reinterpret_cast<char*>(&f), sizeof(f));
  ostrm.write(reinterpret_cast<char*>(&g), sizeof(g));
  ostrm.close();

  std::ifstream istrm("out.dat", std::ios::binary);
  foo f2, g2;
  istrm.read(reinterpret_cast<char*>(&f2), sizeof(f2));
  istrm.read(reinterpret_cast<char*>(&g2), sizeof(g2));
  std::cout << f2 << std::endl << g2 << std::endl;
  istrm.close();

  return 0;
}
  • 模板类继承
#include <iostream>

template <typename T>
class Array {
public:
  Array(std::size_t length_) : length(length_), value(new T[length_]) {
    std::cout << "CTOR of Array called" << std::endl;
    std::cout << "Length: " << length << std::endl;
    std::cout << "Type: " << typeid(T).name() << std::endl;
  }

private:
  std::size_t length;
  T* value;
};

class IntArray : public Array<int> {
public:
  IntArray(std::size_t length_) : Array(length_) {}
};

template <typename T>
class AdvancedArray : public Array<T> {
public:
  AdvancedArray(std::size_t length_) : Array(length) {}
};

template <typename T, std::size_t L>
class ArrayWithLength : public Array<T> {
public:
  ArrayWithLength() : Array(L) {}
};

int main() {
  ArrayWithLength<char, 3> arr1;
  IntArray arr2(5);
  return 0;
}