概念

类其实类似结构体,就是里面可以放函数,然后增添了很多特性

还有就是

struct 默认public

class默认private

类成员函数

放在类里的函数

在类中声明后,可以在类中定义,也可以在类外定义

1
2
3
4
5
6
7
8
9
10
11
12
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度

double getVolume(void)
{
return length * breadth * height;
}
};
1
2
3
4
double Box::getVolume(void)
{
return length * breadth * height;
}

类访问修饰符

public:没什么好说的

private::在类外无法被直接引用

protected:同private,但在派生类的类中可以引用

友元函数

友元函数

友元类

构造函数

struct 默认public

class默认private

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
30
31
32
33
34
35
36
37
#include<iostream>
using namespace::std;

class Student {
private:
string m_name;
int m_age;
float m_score;
public:
void show();
Student(string name, int age, float score);
Student();
};

void Student::show() {
cout << m_name << "年龄" << m_age << "成绩" << m_score;
}

Student::Student() {
cout << m_name << "年龄" << m_age << "成绩" << m_score;
}

Student::Student(string name, int age, float score) {
m_name = name;
m_age = age;
m_score = score;
}

int main() {
Student student("haidragon", 25, 10.1);
student.show();
Student* pstudent = new Student("haidragon", 25, 10.1);
pstudent->show();
delete(pstudent);
return 0;

}

1.构造函数
作用:对象所在的内存空间做初始化 、给对象赋资源
2.析构函数
作用:释放对象所占的其他资源。
3.拷贝构造函数
作用:拿一个已存在的对象来生成相同类型的新对象.
4.赋值运算符的重载函数
作用:拿一个已存在的对象给相同类型的已存在对象赋值.
5.一般对象取地址函数.
6.常对象取地址函数.

C++11以后增加了右值引用的概念,同时增加了移动构造函数、和移动赋值函数。
7.移动构造函数。
8.移动赋值函数。

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
#include <iostream>
using namespace std;
class TestCls
{
public:
int a;
int *p;
public:
TestCls() //无参构造函数
{
std::cout<<"调用无参构造函数"<<std::endl;
p = new int;
}
TestCls (const TestCls & a){
std::cout<<"调用拷贝构造函数"<<std::endl;
}
// void operator = (const TestCls & a){
// std::cout<<"调用赋值构造函数"<<std::endl;
// }
TestCls operator = (const TestCls & a){
std::cout<<"调用赋值构造函数"<<std::endl;
}
TestCls* operator & (){
std::cout<<"调用取地址构造函数"<<std::endl;
}
const TestCls* operator &() const{
std::cout<<"const修饰的取地址操作符重载"<<std::endl;
}
~TestCls() //析构函数
{
delete p;
std::cout<<"调用析构函数"<<std::endl;
}
};

int main(void)
{
TestCls t1;
TestCls t2(t1);
TestCls t3 = t2;
t3 = t1;
TestCls* t4=&t3;
const TestCls* t5=t4;
const TestCls* t6=&t3;
const TestCls t7;
const TestCls* t8=&t7;
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
#include <iostream>
using namespace::std;

void test1(int i, int j) {
int temp = i;
i = j;
j = temp;
}

void test2(int* i, int* j) {
int temp = *i;
*i = *j;
*j = temp;
}

void test3(int& i, int& j) {
int temp = i;
i = j;
j = temp;
}

int main() {
int i = 1;
int j = 2;
printf("%d,%d\n", i, j);
i = 1;
j = 2;
test1(i, j);
printf("%d,%d\n", i, j);
i = 1;
j = 2;
test2(&i, &j);
printf("%d,%d\n", i, j);
i = 1;
j = 2;
test3(i, j);
printf("%d,%d\n", i, j);
return 0;
}


1,2
1,2
2,1
2,1

1、两者的定义和性质不同
指针是一个变量,存储的是一个地址,指向内存的一个存储单元;

引用是原变量的一个别名,跟原来的变量实质上是同一个东西。

int a = 996;
int *p = &a; // p是指针, &在此是求地址运算
int &r = a; // r是引用, &在此起标识作用

上面定义了一个整型变量 a,p 是一个指针变量,p 的值是变量 a 的地址;

而引用 r,是 a 的一个别名,在内存中 r 和 a 占有同一个存储单元。

2、指针可以有多级,引用只能是一级
int **p; // 合法
int &&a; // 不合法

3、指针可以在定义的时候不初始化,引用必须在定义的时候初始化
int *p; // 合法
int &r; // 不合法
int a = 996;
int &r = a; // 合法

4、指针可以指向NULL,引用不可以为NULL
int *p = NULL; // 合法
int &r = NULL; // 不合法
5、修改引用就直接修改被引用对象
int a = 996;
int *p = &a; // 初始化, p 是 a 的地址
int &r = a; // 初始化, r 是 a 的引用

int b = 885;
p = &b; // 合法, p 更改为 b 的地址
r = b;
6、sizeof 的运算结果不同
int a = 996;
int *p = &a;
int &r = a;

cout << sizeof(p); // 返回 int* 类型的大小
cout << sizeof(r); // 返回 int 类型的大小

继承

访问public protected private
同一个类yes yes yes
派生类 yes yes no
外部的类yes no no

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
#include <iostream>

using namespace std;

// 基类
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};

// 派生类
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};

int main(void)
{
Rectangle Rect;

Rect.setWidth(5);
Rect.setHeight(7);

// 输出对象的面积
cout << "Total area: " << Rect.getArea() << endl;

return 0;
}

继承类型
继承类型
当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种类型。继承类型是通过上面讲解的访问修饰符 access-specifier 来指定的。

我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:

公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。

多继承

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
#include <iostream>

using namespace std;

// 基类 Shape
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};

// 基类 PaintCost
class PaintCost
{
public:
int getCost(int area)
{
return area * 70;
}
};

// 派生类
class Rectangle: public Shape, public PaintCost
{
public:
int getArea()
{
return (width * height);
}
};

int main(void)
{
Rectangle Rect;
int area;

Rect.setWidth(5);
Rect.setHeight(7);

area = Rect.getArea();

// 输出对象的面积
cout << "Total area: " << Rect.getArea() << endl;

// 输出总花费
cout << "Total paint cost: $" << Rect.getCost(area) << 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
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
#include <iostream>

class Shape{
public:
void setWidth(int w){
width=w;
}
void setHeight(int h){
height=h;
}
public:
int width;
int height;
};

class PaintCost
{
public:
virtual int getCost(int area)
{
return area * 70;
}
};

class Rectangle{
public: Shape shape;
public:
int getArea(){
return shape.width*shape.height;
}
};

class Rectangle2:public Shape,public PaintCost{
//public: Shape shape;
public:
int getArea(){
return width*height;
}
public:
int getCost(int area)
{
return area * 30;
}
};

int main(){
Rectangle Rect;
Rect.shape.setHeight(3);
Rect.shape.setWidth(3);
int i=Rect.getArea();
Rectangle2 Rect2;
Rect2.setWidth(4);
Rect2.setHeight(5);
i=Rect2.getCost(4);
printf("%d\n",i);
PaintCost* pPaintCost=&Rect2;
i=pPaintCost->getCost(4);
printf("%d\n",i);
return 0;
}

运算符重载

1

命名空间

1