C++一些操作
一、重载
1.1 运算符重载
使用友元函数重载
=,+=,-=,这样的赋值运算,最好使用成员函数,返回运算符左侧的引用,这样既可以连续赋值,又可以直接传递引用,不用调用拷贝构造函数将返回的临时变量复制给左侧参数,增加效率。
ex:重载加法 a+b,友元不属于任何对象,所以它没有this指针
friend test operator +(const test &a,const test &b)
//没有作用域,可以定义多个加法函数,通过哪个重载方法实现只看,传入的参数类型。
{
test temp.private=a.private+b.private;//可以访问private成员
return temp;//因为返回局部变量所以不能用引用
}
使用成员函数重载
成员函数,必定属于一个类,所以会有隐藏的this指针
+,-,/,*这样的运算符,最好使用友元重载,因为左右的参数类型可能不同
ex:重载+,a+b
test test::operator +(const test &b)
{
test temp=this->priavte+b,private;
return temp;
}
1.2 仿函数
- 仿函数不是函数,它是个类;
- 仿函数重载了()运算符,使得它的对你可以像函数那样子调用(代码的形式好像是在调用函数)。
class ShorterThan {
public:
explicit ShorterThan(int maxLength) : length(maxLength) {}
bool operator() (const string& str) const {
return str.length() < length;
}
private:
const int length;
};
count_if(myVector.begin(), myVector.end(), ShorterThan(length));//直接调用即可
1.3 函数重载
#include <iostream>
using namespace std;
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
int main(void)
{
printData pd;
// 输出整数
pd.print(5);
// 输出浮点数
pd.print(500.263);
// 输出字符串
char c[] = "Hello C++";
pd.print(c);
return 0;
}
二、关键字
2.1 default和delete
default用于编译器默认生成的函数,用于默认构造函数,析构函数,拷贝函数以及拷贝赋值函数。如果程序没有显式地为一个类定义某个特殊成员函数,而又需要用到该特殊成员函数时,编译器会隐式地为这个类生成一个默认的特殊成员函数。编译器自动生成的默认特殊构造函数效率高。
class X {
public:
X() = default; // inline
X(const X&); //
X& operator = (const X&);
~X() = default; // inline
}
X::X(const X&) = default; // out of line
X& X::operator = (const X&) = default; // out of line
=delete delete 关键字可用于任何函数,不仅仅局限于类的成员函数
#include <iostream>
using namespace std;
class DataOnly {
public:
DataOnly () {}
~DataOnly () {}
DataOnly (const DataOnly & rhs) = delete; //禁止使用拷贝函数
DataOnly & operator=(const DataOnly & rhs) = delete; //禁止使用拷贝赋值函数
DataOnly (const DataOnly && rhs) {}
DataOnly & operator=(DataOnly && rhs) {}
};
int main(int argc, char *argv[]) {
DataOnly data1;
DataOnly data2(data1); // error: call to deleted constructor of 'DataOnly'
DataOnly data3 = data1; // error: call to deleted constructor of 'DataOnly'
return 0;
}
2.2 explicit关键字
explicit关键字的作用就是防止类构造函数的隐式自动转换。explicit在下面两种情况下有效:
类的构造函数只有一个参数时;类的构造函数中除了第一个参数以外,其他参数都有默认值的时候。(第一个参数可以有默认值,也可以没有)
#include <iostream>
using namespace std;
class A
{
public:
explicit A(int i = 1) : m(i)
{}
int getMa()
{
return m;
}
private:
int m;
};
int main()
{
A a;
cout << "a.m before a=10: " << a.getMa() << endl;
a = 2; //报错
cout << "a.m after a=10: " << a.getMa() << endl;
return 0;
}
double d() const
作用是不改变类成员变量中的数据
2.3 lambda函数
//不带参数的lambda
[]{do_stuff();}();
//带参数列表的lambda
[](int i){std::cout<<i<<std::endl;}();
//有推断返回类型的lambda
[]()->bool{return data_ready;}();
//引用作用域内的局部变量,使用[=]
std::function<int(int)> make_offset(int offset){
return [=](int j){return offset+j;};
}
//[&]
int offset = 32;
std::function<int(int)> offser_a = [&](int j){return offset + j;};
//多个参数
int i = 1234, j = 5678, k = 9;
std::function<int(int)> f = [&i, j, &k]{return i + j + k;}; //j相当于[=]
i = 1;
j = 2;
k = 3;
f(); //其中j = 5678, i = 1, k = 3, 结果为5682.