类
7.5 section
- 构造函数体一开始执行之前,对象内的成员就初始化完成了, 所以 const, reference 以及 某种未提供的默认构造函数的类类型,必须在构造函数初始值列表中间初始化 ```c using namespace std;
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 将按侵权追究法律责任,其它情况随意。