咪哚网

c++知识整理<三>

整理一下自己C++方面的知识,总结一些心得。

类与对象

C++中的类

类是一种将抽象转换为用户定义类型的C++工具,他将数据表示和操作数据的方法组合合成一个整洁的包

构造函数和析构函数

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
26

#include <string.h>

using namespace std;

class {
private:
int a;
char* b;

public:
test(int x,char* y):a(x),b(y){
cout<<a<<endl<<b<<endl;
}

~test(){ //析构函数
cout<<"析构函数调用";
}
};

int main()
{
test(3,"asdasd");

return 0;
}

程序输出为:

1
2
3
3
asdasd
析构函数调用

使用类的时候通过调用构造函数构建该类,一般在构造函数中初始化一系列数值,当类调用结束之后会调用其析构函数,所以一般在这里释放一些存储在堆里面的变量等。

并且析构函数一般定义为 virtual类型,这是因为如果一个父类使用了子类的构造方法,那么,在释放的时候就只会调用父类的析构函数,这样就会导致子类的析构函数没有调用,从而造成内存泄漏
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A 
{
public:
int a;
~A()
{
cout << "A::~A" << endl;
}
};

class B : public A
{
public:
int b;
virtual ~B()
{
cout << "B::~B" << endl;
}
};

此时

1
A* d = new B();

这句话在main函数中调用完毕之后不会调用B中的析构函数,只会调用A中的。
所以在C++在实现多态和继承关系的时候要讲基类的析构函数定义为virtual类型。

运算符重载与友元

在类中用

1
返回值类型 operator 需要重载的运算符 (重载的类型 形参) {}

这样的形式重载运算符。
例如

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

#include <string.h>

using namespace std;

class Test{
private:
int a;
char* b;

public:
Test(int x,char* y):a(x),b(y){
cout<<a<<endl<<b<<endl;
}

int operator+ (int i){
return a+i;
}

~Test(){ //析构函数
cout<<"析构函数调用"<<endl;
}
};

int main()
{
Test t(3,"asdasd");

cout<<t + 3<<endl;

return 0;
}

输出如下

1
2
3
4
3
asdasd
6
析构函数调用

然而这样的重载对于

1
t = 3+t

是不行的。因为在使用重载运算符的时候左侧的操作数是调用对象,也就是说语句

1
A=B+3

将被转换位下面的成员函数调用:

1
A = B.operator+(3);

所以当左侧操作数为非重载运算符的类的时候会出错,不能正确的将语句转换

所以在对于以上二元操作符的时候我们一般采用友元的方式重载运算符(非成员函数)

重载类型如下:

1
Test operator +(int i , const Test & t);

他会将上述语句转换为

1
2
3
4
5
A = operator+(3 , B);

所以成员函数定义的重载和非成员函数定义的重载处理操作数的顺序是反的

创建友元函数的第一步就是将其原型放在类声明中,并在原型声明钱加上关键字friend:

friend Test operator+(int i , const Test & t);

1
该原型意味着以下两点:

虽然operator+()函数是在类声明中声明的,但他不是成员函数,因此不能用成员运算符来调用
虽然operator+()函数不是成员函数,但他拥有和成员函数一样的访问权限`
因此在编写该函数时,不用加上限定符Test::

最近关注