NJU@SE C++ 2025Fall Final 痛苦回忆版

by zeet

简答题

  • 结合 RAII 和栈展开机制,解释为什么会在异常抛出时正确释放资源
  • 更改结构体内变量声明的顺序会不会改变结构体的大小
  • 内联函数和带参数的宏的区别
  • 怎么解决菱形继承中的二义性
  • 为什么 lambda 表达式在按值捕获的时候修改副本需要写 mutable
  • 为什么不允许重载?:运算符
  • 为什么重载后置++返回值而不是引用
  • 移动构造函数相较于拷贝构造函数为什么效率提高了
  • 为什么引用成员和常量成员必须在成员初始化列表中初始化
  • 隐藏和虚函数有什么区别

读程序题

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

int main() {
int x = 10;
const int& y = x;
auto z = y;
z = 20;
cout << x << " " << z;
}

//10 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <climits>
#include <iostream>
using namespace std;

class Complex {
private:
int real;
public:
Complex(int a) : real(a) {}
operator int() {
return real;
}
friend Complex operator+(const Complex& c1, const Complex& c2) {
return Complex(c1.real + c2.real);
}
};

int main() {
Complex a = 10, b = 15;
int c = a + 1;
cout << 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
#include <iostream>
#include <cstring>
using namespace std;

template<typename T>
bool compare(T a, T b) {
cout << "General\n";
return a == b;
}

template<>
bool compare<const char *>(const char* a, const char* b) {
cout << "Specialized\n";
return strcmp(a, b) == 0;
}

int main() {
char s1[] = "hello";
char s2[] = "hello";
compare(s1, s2);
compare("hello", "hello");
}

//General
//Specialized
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <functional>

using namespace std;

function<int()> f() {
int c = 10;
return [&]() {return ++c;};
}

int main() {
auto a = f();
a();
a();
}

//悬垂引用
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
#include <iostream>

using namespace std;

class Base {
public:
virtual void display(int x = 10) {
cout << x << " Base\n";
}
};

class Derived : public Base {
public:
virtual void display(int x = 20) override {
cout << x << " Derived\n";
}
};

int main() {
Base* p = new Derived();
p->display();
delete p;
}

//10 Derived
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
#include <iostream>

using namespace std;

class Base {
public:
Base() {
cout << "Base constructor\n";
func();
}
~Base() {
cout << "Base destructor\n";
func();
}
virtual void func() {
throw 1;
}
};

class Derived : public Base {

};

int main() {
try {
Derived d;
} catch (...) {
cout << "Exception\n";
}
}

//Base constructor
//Exception
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
#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
struct S {
static int v;
};

template <typename T>
int S<T>::v = 0;

struct TagA {};

struct TagB {};

struct A : public S<TagA> {
void add() {
v += 1;
}
};

struct B : public S<TagA> {
void add() {
v += 2;
}
};

struct C : public S<TagB> {
void add() {
v += 3;
}
};

template <typename T>
void modify(T& t) {
t.add();
if constexpr (is_same_v<T, B>) {
t.v += 100;
}
}

int main() {
A a;
B b;
C c;
modify(a);
modify(b);
modify(c);
cout << a.v << " " << b.v << " " << c.v;
}

//103 103 3
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
#include <iostream>
#include <cstring>

using namespace std;

class MyString {
public:
char* data;

MyString(const char* s) {
data = new char[strlen(s) + 1];
strcpy(data, s);
}

~MyString() {
delete[] data;
}

MyString(MyString&& other) {
this->data = other.data;
}
};

int main() {
MyString s1("hello");
MyString s2(std::move(s1));
}

//double free
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
#include <iostream>

using namespace std;

class Base {
private:
int a;
public:
Base() : a(1) {}
void print() {
cout << a;
}
};

class Derived : public Base {
private:
int b;
public:
Derived() : b(2) {}
void print() {
cout << b;
}
};

void p(Base arr[], int n) {
for (int i = 0; i < n; ++i) {
arr[i].print();
}
}

int main() {
Derived d[2];
p(d, 2);
}

//步长不一致
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

using namespace std;

class Base {
public:
Base() {
func();
}
virtual void func() = 0;
};

class Derived : public Base {
public:
virtual void func() override {
cout << "Derived func()\n";
}
};

int main() {
Derived d;
}

//Base的构造函数里面不能调用纯虚函数

设计题

写一个 SmartPtr 模板类,包含构造和析构,重载-><<bool()