1.cpp 关键词
2.cpp 指针
每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using namespace std;
int main()
{
int var1;
int var2[10];
cout << "var1 变量的地址: ";
cout << &var1 << endl;
cout << "var2 变量的地址: ";
cout << &var2 << endl;
return 0;
}1
2
3
4int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */s1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using namespace std;
int main ()
{
int var = 20; // 实际变量的声明
int *ip; // 指针变量的声明
ip = &var; // 在指针变量中存储 var 的地址
cout << "Value of var variable: ";
cout << var << endl;
// 输出在指针变量中存储的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;
// 访问指针中地址的值
cout << "Value of *ip variable: ";
cout << *ip << endl;
return 0;
}
3.cpp引用 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
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
4.文件和流
cpp的标准库fstream提供了 三个类ofstream,ifstream,fstream 对文件进行操作。
1 | //写入模式打开文件 |
5.cpp类构造 1
2
3
4
5
6
7
8
9
10
11
12class Base
{
public:
//公有成员:成员可以在程序外部访问
protected:
//受保护成员:成员在类外部不可访问
private:
//私有成员:成员在类外部不可访问,但是在子类中可以访问
};
6.cpp类的初始化
1 | class Base |
7.cpp类的析构函数 1
2
3
4
5
6class Base
{
public:
Base()//构造函数
~Base()//析构函数;析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源,相当于运行结束后释放对象所占用的资源
};
8.cpp类的继承 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
//单类继承
//基类
class Animal
{
public:
void eat(){std::cout << "I am eating!" << std::endl;}
void sleep(){std::cout << "I am sleeping!" << std::endl;}
};
//子类(派生类)
class derived-class: access-specifier base-class //访问修饰符 access-specifier 是 public、protected 或 private 其中的一个,base-class 是之前定义过的某个类的名称。
class Dog:public Animal
{
public:
void wangwang(){std::cout << "wang wang!" << std::endl;}
};
//多类继承类继承
//基类
class Shape
{
public:
void setwidth(int w){width = w;}
void setheight(int h){height = h;}
private:
int width;
int heiht;
};
//基类
class Paintcost
{
public:
int getcost(int area){return area * 70;}
};
//子类(派生类)
class Rectangle:public Shape,public:PaPaintcost
{
public:
int getarea(){return width * height;}
}
9.cpp函数重载
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。然后通过不同的参数来调用函数的方式称为函数重载
1
2
3
4
5
6
7
8
9
10
11
12
class Printdata
{
public:
void print(int i){std::cout << "整数:"<< i << std::endl;}
void print(double f){std::cout << "浮点数:"<< i << std::endl;}
void print(char []){std::cout << "字符串:"<< i << std::endl;}
//通过不同的参数重载函数
}
10.运算符重载
cpp中可以重定义或重载大部分的cpp内置的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字
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
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//在cpp的类里面使用
Box operator+(const Box&);
//在cpp的类外面使用
Box operator+(const Box&, const Box&);
class Box
{
public:
double getvolum(void){return lenght * breadth * height;}
void setlenght(double len){lenght = len;}
void setbreadth(double bre){breadth = bre;}
void setheight(double hei){height = hei;}
Box operator+(const Box& b)
{
Box box;
box.lenght = this-> lenght + b.lenght;
box.breadth = this -> breadth + b.breadth;
box.height = this -> height + b.height;
return box;
}
double lenght;
double breadth;
double height;
};
int main()
{
Box box1;
Box box2;
Box box3;
double volume1 = 0.0;
double volume2 = 0.0;
double volume3 = 0.0;
box1.setlenght(6.0);
box1.setbreadth(7.0);
box1.setheight(5.0);
box2.setlenght(12.0);
box2.setbreadth(13.0);
box2.setheight(10.0);
std::cout << "Volume of box1 : " << box1.getvolum() << std::endl;
std::cout << "Volume of box2 : " << box2.getvolum() << std::endl;
std::cout << "Volume of box2 : " << (box1+box2).getvolum() << std::endl;
return 0;
}
11.cpp空间命名 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17命名空间这个概念作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。
namespace first_space
{
class Base
{};
}
namespace second_spacee
{
class Base
{};
}
first_space::Base base1
second_space::Base base2
12.cpp的多态
cpp的多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
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
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// 程序的主函数
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();
// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();
return 0;
//结果
//Parent class area :
//Parent class area :
}
导致错误输出的原因是,调用函数 area() 被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为 area() 函数在程序编译期间就已经设置好了。
1 | class Shape { |
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
我们可以把基类中的虚函数 area() 改写如下:
1 | class Shape { |
13.类的抽象
数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。
数据抽象是一种依赖于接口和实现分离的编程(设计)技术。 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
using namespace std;
class Adder{
public:
// 构造函数
Adder(int i = 0)
{
total = i;
}
// 对外的接口
void addNum(int number)
{
total += number;
}
// 对外的接口
int getTotal()
{
return total;
};
private:
// 对外隐藏的数据
int total;
};
int main( )
{
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
//结果
//Total 60
14.cpp动态内存 Cpp程序中的内存分为两个部分:
- 栈:在函数内部声明的所有变量都将占用栈内存
- 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。
很多时候,无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。在
cpp中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即
new 运算符。如果不再需要动态分配的内存空间,可以使用 delete
运算符,删除之前由 new 运算符分配的内存。 1
2double* pvalue = NULL; // 初始化为 null 的指针
pvalue = new double; // 为变量请求内存
如果自由存储区已被用完,可能无法成功分配内存。所以建议检查 new 运算符是否返回 NULL 指针,并采取以下适当的操作:
1 | double* pvalue = NULL; |
15.cpp的this作用类似于python中的self
16.const 修饰成员函数为常函数 * 常函数不能修改成员函数的属性