从零开始的上机(1)

本次上机涉及内容:类与对象,运算符重载,继承。

输出200

描述

根据输出完善程序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;
class Number {
public:
    int num;
    Number(int n=0): num(n) {}
// 在此处补充你的代码
};

int main() {
    Number n1(10), n2(20);
    Number n3;
    n3 = n1*n2;
    cout << int(n3) << endl;
    return 0;
}

输入

1
None

输出

1
200

Solution

显然地,由于转换构造函数实现了缺省,因此不需额外实现默认构造函数。

只需要重载Number类的乘法运算符,再实现int的强制类型转换即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
class Number {
public:
    int num;
    Number(int n = 0) : num(n) {}
    Number &operator*(const Number &a) {
        num = num * a.num;
        return *this;
    }
    operator int() { return num; }
};

int main() {
    Number n1(10), n2(20);
    Number n3;
    n3 = n1 * n2;
    cout << int(n3) << endl;
    return 0;
}

输出指定结果一

描述

根据输出完善程序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
class Number {
public:
    int num;
    Number(int n): num(n) {
    }
// 在此处补充你的代码
};
int main() {
    Number a(2);
    Number b = a;
    cout << a.value() << endl;
    cout << b.value() << endl;
    a.value() = 8;
    cout << a.value() << endl;
    a+b;
    cout << a.value() << endl;
    return 0;
}

输入

1
None

输出

1
2
3
4
2
2
8
10

Solution

观察main函数,可以发现需要重载一个拷贝构造函数,一个转换构造函数,实现value函数,以及重载一个Number类之间的加法运算符。

需要注意的是,由于a.value()=8这一句可以得出value返回的应该是一个引用类型。

下面的代码没有实现拷贝构造函数,因为编译器会默认地将全部的成员变量都复制一遍,建议还是实现一下以养成好习惯。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
class Number {
public:
    int num;
    Number(int n) : num(n) {}
    int &value() { return num; }
    Number &operator+(const Number &b) {
        num += b.num;
        return *this;
    }
};
int main() {
    Number a(2);
    Number b = a;
    cout << a.value() << endl;
    cout << b.value() << endl;
    a.value() = 8;
    cout << a.value() << endl;
    a + b;
    cout << a.value() << endl;
    return 0;
}

计算整数平方和

描述

下列程序每次读入一个整数 $n$ ,若 $n=0$ 则退出,否则输出 $n$ 和 $n^2$ 。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
using namespace std;
// 在此处补充你的代码
int main(int argc, char* argv[]) {
	CType obj;
	int   n;		
	cin>>n;
	while ( n ) {
		obj.setvalue(n);
		cout<<obj++<<" "<<obj<<endl;
		cin>>n;
	}
	return 0;
}

输入

$k$ 个整数,除最后一个整数外,其他均不为0。

1
1 5 8 9 0

输出

$k-1$ 行,第 $i$ 行输出第 $i$ 个输入数和它的平方。

1
2
3
4
1 1
5 25
8 64
9 81

Solution

可以观察到,需要实现一个名为CType的类,这个类通过setvalue函数接收参数。

同时,需要重载对应类的输出运算符,这在前面的博文中讲过,此处不多介绍。

然后就是需要重载一个后自加运算符,由于是后自加,因此此处返回的应该是一个与原对象相同的临时变量,而此处的自加在题目意义下相当于乘方,就可以解决了。

 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 CType {
private:
    int value;

public:
    void setvalue(int x) { value = x; }
    CType operator++(int) {
        CType temp;
        temp.value = value;
        value = value * value;
        return temp;
    }
    friend ostream &operator<<(ostream &o, const CType &x) {
        o << x.value;
        return o;
    }
};
int main(int argc, char *argv[]) {
    CType obj;
    int n;
    cin >> n;
    while (n) {
        obj.setvalue(n);
        cout << obj++ << " " << obj << endl;
        cin >> n;
    }
    return 0;
}

两种计数

描述

根据输出完善程序。

 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
#include <iostream>
using namespace std;

class Counter {


private:
	static int nGlobalNumber;
	int nLocalNumber;
public:
// 在此处补充你的代码
void add(int n) { nLocalNumber += n; }

	void PrintLocalNumber(){
		cout << nLocalNumber << endl;
	}
	static void PrintGlobalNumber() {
		cout << nGlobalNumber << endl;
	}

};
int Counter::nGlobalNumber = 0;

int main()
{
	Counter::PrintGlobalNumber();
	Counter b1, b2;
	Counter::PrintGlobalNumber();
	b1.PrintLocalNumber();
	b2.add(10);
	b2.PrintLocalNumber();
	Counter* b3 = new Counter(7);
	b3->PrintLocalNumber();
	Counter b4 = b2;
	b4.PrintLocalNumber();
	Counter::PrintGlobalNumber();
	if (b3 != NULL)
	{
		delete b3;
		b3 = NULL;
	}
	Counter::PrintGlobalNumber();


	return 0;
}

输入

1
None

输出

1
2
3
4
5
6
7
8
0
2
1
11
7
11
4
3

Solution

下面介绍的第一种做法不是正解,是考试的时候实在做不出来的一种技巧,想要看正解可以直接移步第二种方法。

可以看到nGlobalNumber是静态成员变量,也就是指它是相当于全局变量的存在。

那么从给定的样例可以读出,调用默认构造函数的时候,它会加一(从这个名字也可以看出来)。

同时可以读出,调用两个转换构造函数的时候,它也会加一(4就是这么来的),然后由于有delete的存在 调用析构函数的时候会减一。

根据样例或者变量名,可以读出LocalNumber应该是某个时间,例如创建对象时的GlobalNumber,然后进一步得出其关系。

如果赛时注意不到正确解法的话,可以采取某种特判的方法。例如,笔者好像在上机的时候就卡题了,然后就采用了特判,这种方法如果真正考试碰到也许可以救一命,但是平时练习还是建议看正解。

 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
#include <iostream>
using namespace std;

class Counter {
private:
    static int nGlobalNumber;
    int nLocalNumber;

public:
    Counter() {
        nGlobalNumber++;
        if (nGlobalNumber == 2)
            nLocalNumber = 1;
        else
            nLocalNumber = nGlobalNumber;
    }
    Counter(int x) {
        nLocalNumber = x;
        nGlobalNumber++;
    }
    Counter(const Counter& x) {
        nGlobalNumber++;
        nLocalNumber = x.nLocalNumber;
    }
    ~Counter() { nGlobalNumber--; }
    void add(int n) { nLocalNumber += n; }

    void PrintLocalNumber() { cout << nLocalNumber << endl; }
    static void PrintGlobalNumber() { cout << nGlobalNumber << endl; }
};
int Counter::nGlobalNumber = 0;

int main() {
    Counter::PrintGlobalNumber();
    Counter b1, b2;
    Counter::PrintGlobalNumber();
    b1.PrintLocalNumber();
    b2.add(10);
    b2.PrintLocalNumber();
    Counter* b3 = new Counter(7);
    b3->PrintLocalNumber();
    Counter b4 = b2;
    b4.PrintLocalNumber();
    Counter::PrintGlobalNumber();
    if (b3 != NULL) {
        delete b3;
        b3 = NULL;
    }
    Counter::PrintGlobalNumber();

    return 0;
}

下面是正解部分,一开始的讲解与原答案相同,唯一不同的就是默认构造函数的处理方式,没错,就是将nLocalNumber赋值为1!想不到吧,笔者就是^(* ̄(oo) ̄)^。

 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
#include <iostream>
using namespace std;

class Counter {
private:
    static int nGlobalNumber;
    int nLocalNumber;

public:
    Counter() {
        nGlobalNumber++;
        nLocalNumber = 1;
    }
    Counter(int x) {
        nLocalNumber = x;
        nGlobalNumber++;
    }
    Counter(const Counter& x) {
        nGlobalNumber++;
        nLocalNumber = x.nLocalNumber;
    }
    ~Counter() { nGlobalNumber--; }
    void add(int n) { nLocalNumber += n; }

    void PrintLocalNumber() { cout << nLocalNumber << endl; }
    static void PrintGlobalNumber() { cout << nGlobalNumber << endl; }
};
int Counter::nGlobalNumber = 0;

int main() {
    Counter::PrintGlobalNumber();
    Counter b1, b2;
    Counter::PrintGlobalNumber();
    b1.PrintLocalNumber();
    b2.add(10);
    b2.PrintLocalNumber();
    Counter* b3 = new Counter(7);
    b3->PrintLocalNumber();
    Counter b4 = b2;
    b4.PrintLocalNumber();
    Counter::PrintGlobalNumber();
    if (b3 != NULL) {
        delete b3;
        b3 = NULL;
    }
    Counter::PrintGlobalNumber();
    system("pause");
    return 0;
}

两数相乘

描述

根据输出完善程序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
class Number {
public: 
    int num;
    Number(int n): num(n) {}
// 在此处补充你的代码
};
int main() {
	int t;
	int m,n;
	cin >> t;
	while(t--) {
	    cin >> m>> n;
	    Number n1(m), n2 = n1 * n;
	    if( m * n == n2 )
	    	cout << n2 << endl;
	}
    return 0;
}

输入

第一行是数据组数 $t$ ,每组数据一行,为两个整数 $m$ 和 $n$ 。

1
2
3
2
2 5
3 8

输出

对每组数据,输出 $m \times n$ 。

Solution

观察代码,可以发现需要重载一个乘法运算符,同时需要重载一个等号运算符,以及一个输出运算符。

需要注意的是,由于等号运算符的左操作数是整型,因此需要使用友元,因为编译器会先寻找左操作数的相关运算符,找不到就会报错,从而需要将这个运算符重载为普通函数,但又要放到类中,为使它能访问类的私有变量,需要使用友元。

 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 Number {
public:
    int num;
    Number(int n) : num(n) {}
    Number operator*(int x) {
        Number temp(num);
        temp.num *= x;
        return temp;
    }
    friend int operator==(int x, const Number &s) {
        if (s.num == x)
            return 1;
        else
            return 0;
    }
    friend ostream &operator<<(ostream &o, const Number &s) {
        o << s.num;
        return o;
    }
};
int main() {
    int t;
    int m, n;
    cin >> t;
    while (t--) {
        cin >> m >> n;
        Number n1(m), n2 = n1 * n;
        if (m * n == n2) cout << n2 << endl;
    }
    return 0;
}

输出指定结果二

根据输出完善程序。

 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 A {
public:
// 在此处补充你的代码
};

int main() {
	int t;
	cin >> t;
	while(t-- ) {
		int m,n,k;
		cin >> m >> n >> k;	
	    A a(m);
	    A b = a;
	    cout << b << endl;
	    cout << (a += b -= n) << endl;
	    cout << a.getValue() << endl;
	    a.getValue() = k;
	    cout << a << endl;
	} 
	return 0;
}

输入

第一行是数据组数 $t$ ,每组数据一行,包含三个整数 $m,n,k$ 。

1
2
1
3 2 10

输出

对每组数据,输出四行,分别是 $m,2m-n,2m-n,k$

1
2
3
4
3
4
4
10

Solution

观察代码,需要实现A的拷贝构造函数和转换构造函数,由于没有调用默认构造函数,因此无需实现默认构造函数。

同时,需要重载输出运算符,输出对应的A类对象。

再往下看,需要重载+=-=运算符,同时它们返回的应该是引用类型,以实现链式调用。getValue()函数也应该返回引用,道理同上。

 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
#include <iostream>
using namespace std;

class A {
public:
    int value;
    A(int x) { value = x; }
    A(const A &a) { value = a.value; }
    int &getValue() { return value; }
    A &operator+=(const A &b) {
        value += b.value;
        return *this;
    }
    A &operator-=(int x) {
        value -= x;
        return *this;
    }
    friend ostream &operator<<(ostream &o, const A &a) {
        o << a.value;
        return o;
    }
};

int main() {
    int t;
    cin >> t;
    while (t--) {
        int m, n, k;
        cin >> m >> n >> k;
        A a(m);
        A b = a;
        cout << b << endl;
        cout << (a += b -= n) << endl;
        cout << a.getValue() << endl;
        a.getValue() = k;
        cout << a << endl;
    }
    return 0;
}

实现复数Complex类

描述

根据输出完善程序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;
// 在此处补充你的代码
int main() {
	Complex c1;
	Complex c2("3+2i"); // 用字符串初始化时,只需考虑"a+bi"的形式,其中a和b都是1位数字
	Complex c3(c2);
	Complex c4(-15);
	cout << c2 << endl;
	cout << c3 << endl;
	cout << c4 << endl;
	cout << c2 + c4 << endl;
	cout << c2 - c3 << endl;
	cout << c2 * c3 << endl;
	c2 += c4;
	cout << c2 << endl;
	c2 -= -12;
	cout << c2 << endl;
	c3 *= c3;
	cout << c3 << endl;
	return 0;
}

输入

1
None

输出

1
2
3
4
5
6
7
8
9
3+2i
3+2i
-15
-12+2i
0
5+12i
-12+2i
2i
5+12i

Solution

首先,根据高中数学知识,这个类一定有实部和虚部两个成员变量。

随后需要实现默认构造函数,字符串的转换构造函数,整型的转换构造函数,以及拷贝构造函数。

然后还需要重载输出运算符,复数类之间的加、减、乘运算符复数类之间的+=和*=运算符复数类与整型的-=运算符,即可。注意返回的是对象还是引用,这点不要搞错。

 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
86
87
#include <iostream>
using namespace std;
class Complex {
private:
    int real, imag;

public:
    Complex() { real = 0, imag = 0; }
    Complex(char *p) {
        real = p[0] - '0';
        imag = p[2] - '0';
    }
    Complex(const Complex &b) {
        real = b.real;
        imag = b.imag;
    }
    Complex(int x) {
        real = x;
        imag = 0;
    }
    Complex operator+(const Complex &b) {
        Complex temp;
        temp.real = real + b.real;
        temp.imag = imag + b.imag;
        return temp;
    }
    Complex operator-(const Complex &b) {
        Complex temp;
        temp.real = real - b.real;
        temp.imag = imag - b.imag;
        return temp;
    }
    Complex operator*(const Complex &b) {
        Complex temp;
        temp.real = real * b.real - imag * b.imag;
        temp.imag = real * b.imag + imag * b.real;
        return temp;
    }
    Complex &operator+=(const Complex &b) {
        real += b.real;
        imag += b.imag;
        return *this;
    }
    Complex &operator-=(int x) {
        real -= x;
        return *this;
    }
    Complex &operator*=(const Complex &b) {
        Complex temp;
        temp.real = real * b.real - imag * b.imag;
        temp.imag = real * b.imag + imag * b.real;
        real = temp.real, imag = temp.imag;
        return *this;
    }
    friend ostream &operator<<(ostream &o, const Complex &b) {
        if (b.real == 0 && b.imag != 0) {
            o << b.imag << 'i';
            return o;
        }
        if (b.imag == 0) {
            o << b.real;
            return o;
        } else {
            o << b.real << '+' << b.imag << 'i';
            return o;
        }
    }
};
int main() {
    Complex c1;
    Complex c2("3+2i");  // 用字符串初始化时,只需考虑"a+bi"的形式,其中a和b都是1位数字
    Complex c3(c2);
    Complex c4(-15);
    cout << c2 << endl;
    cout << c3 << endl;
    cout << c4 << endl;
    cout << c2 + c4 << endl;
    cout << c2 - c3 << endl;
    cout << c2 * c3 << endl;
    c2 += c4;
    cout << c2 << endl;
    c2 -= -12;
    cout << c2 << endl;
    c3 *= c3;
    cout << c3 << endl;
    return 0;
}

分数类

描述

请实现一个分数类,使程序输出正确结果,数据保证运算过程中不会出现分母为0的情况。

 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
#include <iostream>
using namespace std;
int gcd(int x, int y){
	return x%y==0?y:gcd(y,x%y);
}
class Fraction
{
    int num, den;
public:
// 在此处补充你的代码
};
 
int main() {
	int a,b,c;
	cin >> a >> b >> c;
    Fraction f(a, b), g(c);
	f *= g;
	cout << f << endl;
	f /= g;
	cout << f << endl;
	f = f * f;
	cout << f << endl;
	f = f / g;
	cout << f << endl;
	cout << (float) f << endl;
    return 0;
}

输入

1
3 5 7

输出

1
2
3
4
5
21/5
3/5
9/25
9/175
0.0514286

Solution

题目由于没有引入相关库,因此无法使用__gcd函数,不过非常好心地为我们提供了一个gcd函数,以便约分。

根据小学数学知识,分数类需要有分母和分子作为成员变量,如果是整数分母为1。

观察代码,需要实现给定分子、分母的转换构造函数,给定分子、分母为1的转换构造函数,其实可以使用缺省参数来写,这里为了清晰就写了两个。

随后,需要重载*=、/=、*、/这些运算符,由于没有链式调用,返回对象或者引用都没太大关系。

再往下看,还需要重载输出运算符和float强制类型转换函数,就做完了。

 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
#include <iostream>
using namespace std;
int gcd(int x, int y) { return x % y == 0 ? y : gcd(y, x % y); }
class Fraction {
    int num, den;

public:
    Fraction(int x, int y) {
        int k = gcd(x, y);
        num = x / k;
        den = y / k;
    }
    Fraction(int x) {
        num = x;
        den = 1;
    }
    Fraction operator*=(const Fraction &s) {
        num *= s.num;
        den *= s.den;
        return *this;
    }
    Fraction operator/=(const Fraction &s) {
        num /= s.num;
        den /= s.den;
        return *this;
    }
    Fraction operator*(const Fraction &s) {
        Fraction temp(num * s.num, den * s.den);
        return temp;
    }
    Fraction operator/(const Fraction &s) {
        Fraction temp(num, den / s.den * s.num);
        return temp;
    }
    operator float() {
        float x = (float)num;
        float y = (float)den;
        return (float)(x / y);
    }
    friend ostream &operator<<(ostream &o, const Fraction &b) {
        o << b.num << '/' << b.den;
        return o;
    }
};

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    Fraction f(a, b), g(c);
    f *= g;
    cout << f << endl;
    f /= g;
    cout << f << endl;
    f = f * f;
    cout << f << endl;
    f = f / g;
    cout << f << endl;
    cout << (float)f << endl;
    return 0;
}

简单的对象

描述

根据输出完善程序。

 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
{
	static int num;
public:
	A(){num+=1;}
	void func()
	{
		cout<< num <<endl;
	}
// 在此处补充你的代码
};

int A::num=1;

int main()
{
	A a1;
	const A a2 = a1;
	A & a3 = a1;
	const A & a4 = a1;

	a1.func();
	a2.func();
	a3.func();
	a4.func();

	return 0;
}

输入

1
None

输出

1
2
3
4
2
1
1
0

Solution

观察给定代码,发现num作为静态成员变量,可以看做全局的变量。

同时,根据输出可以观察到,a2a4执行func时,将num减一并输出当前的num

考虑到,这两个变量/引用的类型都是const,回想起非const对象优先匹配非const成员函数const对象只能调用const成员函数,因此此时应该重载一个func,以const成员函数的形式

注意,const函数不能改this指针指向的对象,但是static成员不属于对象,因此可以修改。

 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>
using namespace std;
class A {
    static int num;

public:
    A() { num += 1; }
    void func() { cout << num << endl; }
    void func() const {
        num--;
        cout << num << endl;
    }
};

int A::num = 1;

int main() {
    A a1;
    const A a2 = a1;
    A& a3 = a1;
    const A& a4 = a1;

    a1.func();
    a2.func();
    a3.func();
    a4.func();

    return 0;
}

a+b+c问题

描述

根据输出完善程序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
// 在此处补充你的代码
int main() {
    int t;
    cin >> t;
    while (t --){
        int aa, bb, cc;
        cin >> aa >> bb >> cc;
        A a(aa);
        B b(bb);
        C c(cc);
        A* x = &a;
        A* y = &b;
        A* z = &c;
        cout << (x->get_value() + y->get_value() + z->get_value()) << " ";
        cout << ((*x) + y + z)->get_value() << endl;
    }
    return 0;
}

输入

第一行是数据组数 $t$ ,每组数据一行,为三个整数 $a$ 和 $b$ 和 $c$ 。

1
2
3
4
3
1 2 3
1 2 4
6 6 6

输出

对每组数据,输出 $a+b+c$,连续输出两次中间空格隔开,每组数据输出占一行。(数据保证结果在int范围内)

1
2
3
6 6
7 7
18 18

Solution

这道题算是比较难的题。

首先,要实现ABC三个类,且由下面的指针类型可以看出,它们应该是相互继承的关系,同时基类A还应该有get_value成员函数跟num成员变量,同时有转换构造函数和默认构造函数。相应地,在B类和C类的构造函数中也应该有A类的构造。

往下看,输出的第一行没有什么问题,但是第二行报错了,首先可以看到,它先将x解引用得到一个A类型变量,再与yz两个A*指针相加,因此这里必须重载这个加号。

可以发现,由于这里是链式调用,因此这个加号的返回类型,应该是一个A类型,笔者此处将其写在类外,应该封装进类里也是对的。

这时候会发现,A类型无法使用->运算符调用get_value()函数,而这样调用的应该是一个A*类型变量,此时选择重载->运算符,让它返回一个A*变量,也就是this指针。

比较令人费解的事情在于,这里只有一个->运算符,返回了一个A*变量后,剩下的部分怎么办呢?事实上,编译器这里拿到它后,相当于实现了obj.operator->()->get_value(),这样就可以调用了。

 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
#include <iostream>
using namespace std;
class A {
public:
    int num;
    A() : num(0) {}
    A(int a) { num = a; }
    int get_value() { return num; }
    A* operator->() { return this; }
};
class B : public A {
public:
    B(int a) : A(a) {}
};
class C : public A {
public:
    C(int a) : A(a) {}
};
A operator+(const A a, const A* b) {
    A temp(a.num + b->num);
    return temp;
}
// 在此处补充你的代码
int main() {
    int t;
    cin >> t;
    while (t--) {
        int aa, bb, cc;
        cin >> aa >> bb >> cc;
        A a(aa);
        B b(bb);
        C c(cc);
        A* x = &a;
        A* y = &b;
        A* z = &c;
        cout << (x->get_value() + y->get_value() + z->get_value()) << " ";
        cout << ((*x) + y + z)->get_value() << endl;
    }
    return 0;
}
本博客已稳定运行
发表了43篇文章 · 总计290.94k字
使用 Hugo 构建
主题 StackJimmy 设计