Skip to the content.

类

7.5 section

class A { public: A() { cout « “cons” « endl; }

A(const A &a) { cout « “copy” « endl; }

A &operator=(const A &a) { cout « ”=” « endl; return *this; } };

class B { A _a;

public: B(A a) : _a(a) { cout « “B” « endl; } B(A a, int x) { _a = a; cout « “B = “ « endl; } };

int main(int argc, char *argv[]) { A a;

cout « ”——” « endl; B b(a); cout « ”——” « endl; B b1(a, 1); return 0; }


cons —— copy copy B —— copy cons // A 已经被初始化过一次了, 但是如果初始化列表就不会出现这种情况 = B =


- 构造函数初始化列表不会保证顺序
- 委托构造函数 : 使用其他的构造函数来实现构造函数


- [ ] 7.5.3 中间分析了 value initialization 和 default initialization :
    - 相关的讨论 : https://stackoverflow.com/questions/3803153/what-are-primitive-types-default-initialized-to-in-c
    - new T 和 new T{} / new T() : 前者是 default initialization[^1],后者是 value initialization [^2]
    - 关于 new 和 new () 在[^3] 中间提供了一堆例子
      - value initialization 的作用在于 : 当 compiler 提供的 default constructor 对于数值不初始化的,但是 value initialization 机制可以将其初始化为 0
    - 大家的建议就是不要使用使用这种 corner case 的东西 [^4]

[^1]: https://en.cppreference.com/w/cpp/language/default_initialization
[^2]: https://en.cppreference.com/w/cpp/language/value_initialization
[^3]: https://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new
[^4]: https://stackoverflow.com/questions/2417065/does-the-default-constructor-initialize-built-in-types


- 使用默认构造函数 `A a;` 而不是 `A a()`
- 只允许一步类型转换
- [ ] 关于 aggregate class 书上只是说明了其定义,初始化方法 和 三个明显的缺点,但是为什么我们需要 aggregate class
  - https://stackoverflow.com/questions/31232288/what-are-aggregate-classes-for
  - https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special

- constexpr
  - `constexpr const int * p = &i` : p 是 constexpr 指针,指向 int 常量, i 必须定义在函数外面
  - constexpr 要求返回类型和所有形参类型都是字面值类型, 函数体中间有且仅有一个 return 语句 (可以存在一些不产生动作的语句, 比如 using 和 decltype)
    - [ ] 可以是字面值 class 吗 ?
  - constexpr 函数不一定返回常量表达式,参数也不一定需要是 const 或者 constexpr
  - literal class
    - 成员都是 literal type 的 aggregate class
    - 或者满足下面的所有条件:
      1. 成员都是 literal type
      2. 至少一个 constexpr 构造函数
      3. 所有的成员都可以被 "explicit" 的初始化 (通过类内初始值,或者 constructor)
      4. 析构函数默认定义

```cpp
constexpr int fuck(int x ){
  using namespace std;
  return 12 * x;
}

int main(int argc, char *argv[]){
  constexpr int x = 12;

  int i = 12;
  scanf("%d", &i);
  const int y = 123;
  int a = fuck(i); // 可以 !
  constexpr int b = fuck(9);
  constexpr int c = fuck(x);
  constexpr int d = fuck(y);
  // constexpr int c = fuck(i); // 不可以

  return 0;
}
class C1 {
public:
  constexpr C1(int i) : x(i) {}
  int x;
};

class C2 {
  int y;

public:
  int x;
  C1 c1;
  constexpr C2() : y(), x(), c1(2) {}

  C2(int x): c1(12){

  }
};

constexpr int get_x1(C1 c) { return c.x; }

constexpr int get_x2(C2 c) { return c.x; }

class A {
public:
  int a;

};

int main(int argc, char *argv[]) {
  constexpr C2 a;  // 因为 x 需要是 constexpr ,所以必须将 a 声明为 constexpr 对象
  // 如果 x 没有这个要求,那么就可以不添加

  constexpr int x = get_x2(a);

  constexpr A g = {12};
}

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。