C++八股随记
函数重载
1
2
3
4
5
6
7
8
9
10
struct A {
A() {}//构造函数
~A() {}
float operator+(const float& x);
float operator-(const A& x);
int operator()(std::string s, int x, float y);
};
float operator+(const int& x, const A& y);//全局重载运算符
operator()
是仿函数来的,就可以让对象假装函数,我觉得我是函数:
1
2
3
4
5
int main()
{
A a1;
int k = a1("abc", 1, 1.0);
}
仿函数
仿函数是配合STL进行使用,用于方便模板类和模板函数。
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
template<typename T> // 加入模板声明
class print {
public:
print(T j) : m_j(j) // 正确的构造函数初始化列表
{
cout << "This is print" << endl;
}
void operator()(int i) // 输出比 m_j 小的整数
{
if(i < m_j)
cout << i << endl;
}
void operator()(string i) // 打印字符串长度小于 m_j 的字符串
{
if (i.size() < m_j)
cout << i << endl;
}
void operator()(double i) // 打印比 m_j 小的 double
{
if (i < m_j)
cout << i << endl;
}
private: // 将 m_j 设为私有
T m_j;
};
int main(int argv, char* argc[])
{
vector<int> it1 = { 1, 2, 3, 4, 6, 7, 8 };
for_each(it1.begin(), it1.end(), print<int>(5)); // 使用模板实例化
vector<string> it2 = { "123", "12345", "123436", "1343253245" };
for_each(it2.begin(), it2.end(), print<size_t>(5)); // 使用 size_t 作为模板类型,因为字符串大小是 size_t 类型
vector<double> it3 = { 1.1, 2.3, 3.4, 4.7, 6.9, 7.1 };
for_each(it3.begin(), it3.end(), print<double>(5.0)); // 使用 double 作为模板实例化
return 0;
}
C++有哪几种构造函数
- 默认构造函数
- 初始化构造函数
- 移动构造函数
- 拷贝构造函数
- 类型转换构造函数
- 委托构造函数
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
#include <iostream>
using namespace std;
class Student{
public:
Student(){//默认构造函数,没有参数
this->age = 20;
this->num = 1000;
};
Student(int a, int n):age(a), num(n){}; //初始化构造函数,有参数和参数列表
Student(const Student& s){//拷贝构造函数,这里与编译器生成的一致
this->age = s.age;
this->num = s.num;
};
Student(int r){ //转换构造函数,形参是其他类型变量,且只有一个形参
this->age = r;
this->num = 1002;
};
Student(const char* name, double score)// 接受任意类型指定参数的构造函数,
{
this->age = 0;
this->num = (int)score;
}
Student(double r){ //转换构造函数,形参是其他类型变量,且只有一个形参
this->age = (int)r * 10;
this->num = 1003;
};
~Student(){}
public:
int age;
int num;
};
int main(){
Student s1;
Student s2(18,1001);//初始化构造函数调用
int a = 10;
Student s3(a);//重载构造函数调用,传参数形式
Student s4(s3);
Student s5("Demo",56.45);//重载构造函数调用
Student s6 = 85.63;//证明为转换构造函数调用
float b = 5.2;
Student s7 = b;//为转换构造函数调用,带有隐式类型转换
printf("s1 age:%d, num:%d\n", s1.age, s1.num);
printf("s2 age:%d, num:%d\n", s2.age, s2.num);
printf("s3 age:%d, num:%d\n", s3.age, s3.num);
printf("s4 age:%d, num:%d\n", s4.age, s4.num);
printf("s5 age:%d, num:%d\n", s5.age, s5.num);
printf("s6 age:%d, num:%d\n", s6.age, s6.num);
printf("s7 age:%d, num:%d\n", s7.age, s7.num);
return 0;
}
//运行结果
//s1 age:20, num:1000
//s2 age:18, num:1001
//s3 age:10, num:1002
//s4 age:10, num:1002
//s5 age:0, num:56
//s6 age:850, num:1003
//s7 age:50, num:1003
虚拟基类
是 C++ 中在多重继承情况下,通过虚拟继承方式共享基类的机制,避免了多个派生类对同一基类的重复继承和重复构造。
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
#include <iostream>
using namespace std;
class A {
public:
int x;
A() : x(10) { cout << "A's constructor" << endl; }
};
class B : virtual public A {
public:
void setB(int val) { x = val; }
};
class C : virtual public A {
public:
void setC(int val) { x = val; }
};
class D : public B, public C {
public:
D() { cout << "D's constructor" << endl; }
void print() { cout << "x = " << x << endl; }
};
int main() {
D obj;
obj.setB(20);
obj.print(); // 输出 "x = 20"
return 0;
}
输出
1
2
3
A's constructor
D's constructor
x = 20
假如B类和C类不使用虚拟基类,就会导致D类重复构造。
构造函数的执行顺序
- 虚拟基类的构造函数(多个虚拟基类按继承顺序执行)
- 基类的构造函数(多个普通基类也按继承顺序执行)
- 类类型的成员对象的构造函数(按成员在类中的定义顺序)
- 派生类自己的构造函数
成员初始化列表快一些
构造器中做赋值操作,会产生临时对象,初始化列表是直接赋值。
本文由作者按照 CC BY 4.0 进行授权