1.命名空间
命名空间的出现是为解决命名冲突。
namespace namespaceA{
int a = 100;
}
namespace namespaceB{
int a = 2999;//这里可以定义变量,也可以定义结构体
}
int main() {
using namespace namespaceA;
cout<<" a= "<<namespaceA::a<<endl;
using namespace namespaceB;
cout<<" a= "<<namespaceB::a<<endl;
return 0;
}
输出结果为:
a= 100
a= 2999
2.C++的bool类型的值只可能是0或者1
3.C++的引用
C++中的引用跟指针类似,相当于对象的别名,改应用的值,就相当于改对象的值。引用类型在编译后,编译器会将引用类型转化为常量指针。
引用的定义:
int a = 10;
int &b = a;//这里我们称b为a的引用,相当于给a取了个别名。
使用:
#include <iostream>
using namespace std;
void swap1(int *a ,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
void swap2(int &a,int &b){
int temp = a;
a = b;
b = temp;
}
void test1(){
int a = 10;
int b = 20;
swap1(&a,&b);
cout<<"test1 a ="<<a<<" b = "<<b<<endl;
}
void test2(){
int a = 10;
int b = 20;
swap2(a,b);
cout<<"test2 a ="<<a<<" b = "<<b<<endl;
}
int main(){
test1();
test2();
}
输出结果为:
test1 a =20 b = 10
test2 a =20 b = 10
4.写C++的程序一定要自己定义的对象是分配在堆区还是栈区。分配到方法栈区的对象,当方法执行完后,栈空间会被系统回收掉,所以对象也会被系统回收掉,所以不能作为结果用return返回出去。分配到堆区的对象,用完记得释放掉。
一般通过静态申请的内存都在栈上,系统会自动帮我们释放,如果是通过malloc动态申请的内存,都是堆中,必须我们自己释放。
5.C++中类文件的使用
我们用Clion创建一个C++ 的类文件Teacher时,Clion会默认给我们创建两个文件,一个是Teacher.h的头文件,另一个是Teacher.cpp实现文件。如果我们想在其他地方引用我们定义的Teacher类,则只需要在该类中 #include "Teacher.h"即可。
6.如果有局部变量和成员变量同名,在局部作用域如何访问成员变量呢?
在变量名之前加::即可
7.如何调用类的构造函数
class Student{
public:
Student();//无参构造函数
Student(int age);//一个参数构造函数
Student(char *name,int age);//两个参数构造函数
char name[100];
const int score = 100;
int age;
void goHome();
};
int main(){
//第一种
Student student;//调用无参构造函数
Student student1("小明",16);//调用有参构造函数
//第二种
Student student2 = ("小红",15);//这种通过“=”只能调用一个参数的构造函数,前面的参数“小红”是没有用的。
Student student3 = 15;//正确写法
//第三种
Student student4 = Student();
Student student5 = Student("Tom",17);
//赋值操作
student = student5;
//这里的操作不是赋值操作,而是调用了拷贝构造函数
Student student6 = student5;
Student student7(student5) ;
//如果对象在“=”操作之前,就已经初始化了,这里就是赋值操作,如果没有初始化,那就是初始化操作,会调用构造函数。
}
8.当我们在调用函数传值的时候,系统会调用对象的拷贝函数初始化形参,给形参赋值。
void setStudent(Student st1){
cout<<" st1.age = "<<st1.age<<endl;
}
int main(){
Student student1("小明",16);
setStudent(student1);//这里调用函数,系统会调用Student 的拷贝函数,给函数的形参st1赋值。
}
9.默认拷贝函数只可以完成对象的数据成员的简单复制,传值。当对象的数据资源是由指针指向堆内存时,我们就需要进行深拷贝。
10.构造函数初始化列表
一般类中有成员变量是有有参的构造函数需要初始化,或者是有常量需要初始化,就会拥戴初始化列表。
基本语法
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){
//TODO:
}
举例 :
Student::Student(char *str ,int a) :age(a) {//这里相当于用a直接给age赋值了
strcpy(name,str);
}
初始化列表里面初始化的顺序是按照我们成员变量申明的顺序,不是初始化列表的顺序。
11.new 、delete 关键字的使用
int main(){
int *p = new int;//这里使用new 关键字申请一块int类型大小的内存,动态申请的,都在堆里面。
*p = 15;
cout << "delete前 p =" << *p << endl;
delete p;//这里用delete 关键字将申请的内存释放掉。
cout << "delete后 p =" << *p << endl;
//以下是C语言的写法
int *p1 = (int *) (malloc(sizeof(int)));
*p1 = 100;
cout << "free前 p1 =" << *p1 << endl;
free(p1);
cout << "free后 p1 =" << *p1 << endl;
//数组的用法
int *arr = new int[10];
delete[] arr;
//引用对象的用法
Student *student = new Student(15);
delete student;
}
输出结果:
delete前 p =15
delete后 p =3252544
free前 p1 =100
free后 p1 =3252544
delete后的值在不同的环境可能有不同表现,有些地方delete后,p的值打印出来还是15,由于变量进行了了delete操作后,他对应的内存就被进行了特殊标记,而并没有被清理掉,当有其他变量需要申请内存时,这块被标记的内存的就可以使用。
12.malloc/calloc 和new 的区别
- malloc/calloc 是C语言里面的概念,是函数,纯粹的在堆上分配内存给你用。
- new 属于C++里面的概念,是运算符,不属于函数,通过new 分配对象内存的时候,会调用对象的构造函数,同时调用free的时候,也会调用对象的析构函数。
13.类中的非静态函数可以访问静态变量,但静态函数不能访问非静态变量
14.运算符重载
运算符重载就是重新定义运算符的意义,比如“+”在java 中能做字符串的拼接。我想让两个对象相“+”后得到一个新的对象,并且两个对象的年龄也相加。实现如下:
Student operator+(Student st1,Student st2){
Student student(st1.age+st2.age);
return student;
}
int main(){
Student student1(10);
Student student2(20);
Student student3 = student1+student2;//这里其实就是函数的调用
cout<<"student3 age= "<<student3.age<<endl;
}
输出结果为:
student3 age= 30
语法是operator+操作符+参数;
注意,并不是所有的运算符都可以重载
- . 成员访问运算符不能重载
- .*,-> 成员指针访问运算符不能重载
- :: 域运算符不能重载
- sizeof 长度运算符不能重载
- ?:三元运算符不能重载
- # 预处理符号不能重载