1. 求1+2+3+...+n
题目要求和,但是像循环,递归,求和公式这样的方法都不让用,这种情况下我们最先想到的就是static成员变量的使用。我们每创建一个类对象就会调用一下构造函数,加上static修饰后出局部作用域不会销毁,这给我们提供了一个思路。
我们先重新创建一个Sum类,成员变量是静态成员变量,成员函数一个是对调用次数进行累加的,一个是返回最终结果的静态成员函数。
class Sum
{
public:
Sum()
{
_ret += _i; //_ret初始为0,_i初始为1
_i++; //_i自增,实现1+2+3...+n的结果
}
static int GetSum()
{
return _ret;
}
private:
static int _i;
static int _ret;
};
//类外初始化静态成员函数
int Sum::_i = 1;
int Sum::_ret = 0;
而在题目给的Solution类里面,成员函数Sum_Solution中,我们需要对Sum类创建n个大小的变长数组,这样Sum的构造函数就可以被调用n次,就能实现1+2+...+n了。
class Solution
{
public:
int Sum_Solution(int n)
{
Sum a[n];
return Sum::GetSum();
}
};
我们学了内部类,也可以把Sum这个类当作一个Solution类的内部类实现。
class Solution
{
private:
static int _i;
static int _ret;
class Sum //内部类
{
public:
Sum()
{
_ret += _i;
_i++;
}
};
public:
int Sum_Solution(int n)
{
Sum a[n];
return _ret;
}
};
int Solution::_i = 1;
int Solution::_ret = 0;
最后看一下两种方法的对比。
2.构造函数和析构函数调用顺序问题
设已经有A、B、C、D四个类的定义,程序中A、B、C、D构造函数的调用顺序为?析构函数的调用顺序为?
C c;
int main()
{
A a;
B b;
static D d;
return 0;
}
先说构造。全局变量是在进main函数之前就创建好了,所以c的构造函数最先调用,a和b谁在前谁先调用构造,所以a的构造函数肯定在b前面调用,那a、b两个和d相比哪个先调用?答案还是a、b先调用,当程序运行到d时才调用。所以最终顺序就是c a b d。
再看析构。先看最简单的,a和b,我们说过先定义后析构,所以b比a先调用构造函数。再来看d和c,d和c的生命周期是全局的,先析构d然后c。所以最终顺序是b a d c。
3.初始化顺序问题
下面代码结果是什么?
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
:_a1(a)
,_a2(_a1)
{}
void Print()
{
cout << _a1 << " " << _a2 << endl;
}
private:
int _a2 = 2;
int _a1 = 2;
};
int main()
{
A a(1);
a.Print();
return 0;
}
结果是:1 随机值
因为先声明的先初始化,_a2比_a1先声明。先初始化_a2,在初始化列表里面是要用_a1去初始化它,而此时的_a1还没初始化,是个随机值,所以就是一个随机值初始化_a2;然后再初始化_a1,在初始化列表里用参数a初始化,a传的值是1,所以_a1就是1.