C++的一些特性(3)

C++的一些特性(3)

列表初始化

用一对大括号可以给一个数组,结构体,甚至是对象成员初始化。

数组

1
2
3
4
5
6
7
#include<iostream>
using namespace std;
char s[] = {'x','i','a','0','j','i','2','3','3'};
int main() {
puts(s);
system("pause");
}

结构体

初始化,传参,返回都可以。

初始化结构体

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
using namespace std;
typedef struct __Info {
int a;
double b;
}Info, * PInfo;
int main() {
Info s = { 1,1.5 };
printf("%d %lf\n", s.a, s.b);
system("pause");
}

传参

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
using namespace std;
typedef struct __Info {
int a;
double b;
}Info, * PInfo;
void func(Info s) {
printf("%d %lf\n", s.a, s.b);
}
int main() {
func({ 1,1.5 });
system("pause");
}

返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
using namespace std;
typedef struct __Info {
int a;
double b;
}Info, * PInfo;
Info func() {
return { 1,1.5 };
}
int main() {
//func({ 1,1.5 });
Info s = func();
printf("%d %lf\n", s.a, s.b);
system("pause");
}

对象

成员变量初始化

1
2
3
4
5
6
7
8
9
10
#include<iostream>
using namespace std;
class A {
public:
int n{ 1 };
std::string s{ "123" };
};
int main() {
system("pause");
}

函数属性声明

可以在声明函数之后跟一个 = xxx 来声明一个函数的属性,default 表示显式缺省函数,delete 表示显式删除函数,前面还学到过 =0 表示纯虚函数,如果定义为已删除的话就不能够使用这个函数了。

例如:需要禁止拷贝构造函数的使用。以前通过把拷贝构造函数声明为private访问权限,这样一旦使用编译器就会报错。

而在C++11中,只要在函数的定义或者声明后面加上”= delete”就能实现这样的效果(相比较,这种方式不容易犯错,且更容易理解)

联合体的性质

联合体每个不同的定义共用内存,一般来说一个定义只能为基础类型而不能为复杂类,如果要包含复杂类,则需要在联合体内实现构造函数和析构函数让它能被处理。

类的一些其它性质

指定父类构造函数

之前有遇到过,在继承的关系中,我们生成派生类必须调用父类的构造函数,但是却不能指定调用,就会很难受,今天知道了如何指定调用父类的构造函数,之前我是使用了 Child.father::father() 的形式调用,但是出现了巨多的问题,实际上我们指定去调用父类的构造函数可以这么写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
using namespace std;
class A {
public:
A() {
std::cout << "A无参构造" << std::endl;
}
A(int x,double y) {
n = x;
d = y;
std::cout << "A带参构造" << std::endl;
};
int n;
double d;
};
class B:public A
{
public:
B() {
std::cout << "B无参构造" << std::endl;
}
B(int x, double y) :A(x, y) {
std::cout << "B带参构造" << std::endl;
}
~B() {};
};
int main() {
B obj(1, 2.5);
system("pause");
}

构造函数继承

在类当中我们可以 using 父类的构造函数以便于我们不需要写子类的构造函数,这么写的作用是告诉编译器我需要编译器自动产生所有的转发函数,这行为就叫继承构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
using namespace std;
class A {
public:
A() {
std::cout << "A无参构造" << std::endl;
}
A(int x,double y) {
n = x;
d = y;
std::cout << "A带参构造" << std::endl;
};
int n;
double d;
};
class B:public A
{
public:
using A::A;
B() {
std::cout << "B无参构造" << std::endl;
}
~B() {};
};
int main() {
B obj(1, 2.5);
system("pause");
}

委托构造

比如有一个对象,它有两个成员,我希望默认构造的情况下委托带参构造帮我初始化某些成员,那么可以在默认构造后面加上那个带参构造委托它来完成构造。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
using namespace std;
class A {
public:
A():A(0,0) {
std::cout << "A无参构造" << std::endl;
}
A(int x,double y) {
n = x;
d = y;
std::cout << "A带参构造" << std::endl;
};
int n;
double d;
};
int main() {
A obj;
system("pause");
}

练习:手写STL库

就随便写一个阉割版的 vector 吧,实现了基本的插入删除功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#pragma once

template<typename T>
class Vector
{
public:
Vector();
Vector(int n);
~Vector();
void InitArray(int n);
int length();
T& operator[](int index);
void push_back(T val);
T pop_back();
bool empty();

public:
T* base;
int len;
int top;
};

template<typename T>
inline Vector<T>::Vector()
{
this->InitArray(5);
}

template<typename T>
inline Vector<T>::Vector(int n)
{
this->InitArray(n);
}

template<typename T>
inline Vector<T>::~Vector()
{
delete this->base;
}

template<typename T>
inline void Vector<T>::InitArray(int n)
{
this->base = new T[n];
this->len = n;
this->top = 0;
}

template<typename T>
inline int Vector<T>::length()
{
return this->top;
}

template<typename T>
inline T& Vector<T>::operator[](int index)
{
return this->base[index];
}

template<typename T>
inline void Vector<T>::push_back(T val)
{
if (this->top == this->len) {//add 32
T* tmp = new T[this->len + 32];
memcpy(tmp, this->base, this->len * sizeof(T));
delete this->base;
this->base = tmp;
this->len += 32;
}
this->base[top++] = val;
}

template<typename T>
inline T Vector<T>::pop_back()
{
if (top == 0)return T();
return this->base[--top];
}

template<typename T>
inline bool Vector<T>::empty()
{
return this->top == 0;
}
文章目录
  1. 1. 列表初始化
    1. 1.1. 数组
    2. 1.2. 结构体
      1. 1.2.1. 初始化结构体
      2. 1.2.2. 传参
      3. 1.2.3. 返回
    3. 1.3. 对象
      1. 1.3.1. 成员变量初始化
  2. 2. 函数属性声明
  3. 3. 联合体的性质
  4. 4. 类的一些其它性质
    1. 4.1. 指定父类构造函数
    2. 4.2. 构造函数继承
    3. 4.3. 委托构造
  5. 5. 练习:手写STL库
|