一直更新
一:使用stringstream转换类型
头文件:#include <sstream>
以int-string为例:
string->int:
string str = "123";
stringstream ss(str);
int num = 0;
ss>>num;
cout << num;
int->string:
int num = 555;
stringstream ss;
ss<<num;
string str = ss.str();//ss>>str
cout << str;
二:setw()对齐和setfill()填充
头文件:#include <iomanip>
使用setw(n)设置输出宽度时,默认为右对齐。
using namespace std;//!!
cout << setw(8) << setfill('*') << 1 << endl;
cout << setw(8) << setfill('*') << 100 << endl;
cout << setw(8) << setfill('*') << 1000 << endl;
cout << setw(8) << setfill('*') << 10000 << endl;
*******1
*****100
****1000
***10000
左对齐:
using namespace std;
cout << left << setw(8) << setfill('*') << 1 << 2 << endl;
cout << left << setw(8) << setfill('*') << 10 << 20 <<endl;
cout << left << setw(8) << setfill('*') << 100 << 200 << endl;
cout << left << setw(8) << setfill('*') << 1000 << 2000 << endl;
1*******2
10******20
100*****200
1000****2000
我们在设置域宽和填充字符的时候要注意几点:
①设置域宽的时候应该填入整数,设置填充字符的时候应该填入字符。
②我们可以对一个要输出的内容同时设置域宽和 填充字符,但是设置好的属性仅对下一个输出的内容有效,之后的输出要再次设置。即 cout <<setw(2) <<a <<b;语句中域宽设置仅对a有效,对b无效。
三:#define
define有边际效应,就是按原样替换,没括号就是没括号,不计算任何值。
#define M(x,y,z) x*y+z
int main()
{
int a=1, b=2, c=3;
printf("%d\n",M(a+b,b+c,c+a));
}
输出为12不是19,因为宏展开为:a+b*b+c+c+a = 12
如果宏定义为:#define M(x,y,z) (x)*(y)+z:(a+b)*(b+c)+ c + a = 19
四:浮点数精度控制
#include <iomanip>
using namespace std;
double d = 1.2;
cout << setprecision(3) << d << endl;
//1.2
如果我们想要让它自动补0,需要在cout之前进行补0的定义。代码如下:
using namesapce std;
double d = 1.2;
cout.setf(ios::fixed);
cout << setprecision(3) << d << endl;
//或者
cout << fixed << d << endl;
//1.200
若想关闭补零,则
cout.unsetf(ios::fixed);
即可。
五:const成员函数和变量
在类中,如果你不希望某些数据被修改,可以使用const
关键字加以限定。const 可以用来修饰成员变量和成员函数。
需要强调的是,必须在成员函数的声明和定义处同时加上 const 关键字:
class Student {
private:
int age;
public:
void show() const;
};
void Student::show() const {
cout << "age: " << age << endl;
}
最后再来区分一下 const 的位置:
- 函数开头的 const 用来修饰函数的返回值,表示返回值是 const 类型,也就是不能被修改,例如
const char * getname()
。 - 函数头部的结尾加上 const 表示常成员函数,这种函数只能读取成员变量的值,而不能修改成员变量的值,例如
char * getname() const
。
六:类模板
1:类内调用自己不需要定义为Data<T>
template<class T>
class Data {
private:
T value;
public:
Data(T _value=0):value(_value) {}
T getValue() {
return value;
}
Data operator+(Data data) {
Data d(value+data.getValue());
return d;
}
friend ostream& operator<<(ostream &os, Data d) {
os << setprecision(2) << fixed << d.getValue();
return os;
}
};
2:其他类要调用类模板声明的类
template<class T>
class GetResult {
public:
static Data<T> getSum(Data<T> *arr, int num) {
Data<T> sum;
for(int i = 0; i<num; i++) {
sum = sum + arr[i];
}
return sum;
}
};
3:如果友元函数要在类外定义
template<class T>
class Data {
private:
T value;
public:
Data(T _value=0):value(_value) {}
T getValue() {
return value;
}
template<class TT>
friend ostream& operator<<(ostream &os, Data<TT> d);
};
template<class TT>
friend ostream& operator<<(ostream &os, Data<TT> d) {
os << setprecision(2) << fixed << d.getValue();
return os;
}
4:类内函数在外实现:
template<class T>
class Data {
private:
T value;
public:
Data(T _value=0):value(_value) {}
T getValue() {
return value;
}
Data<T> operator+(Data<T> data);
};
template<class T>
Data<T> Data<T>::operator+(Data<T> data) {
Data<T> d(value + data.getValue());
return d;
}