目录 C与C++的区别 C++的类 C++类的成员函数 C++类的封装
C++的构造函数 C++的继承和派生 C++的多态 文件夹过滤 C与C++的区别 C语言的Struct只能包含变量,而C++中的class除了可以包含变量,还可以包含函数。C语言中可以通过结构体来定义变量,C++可以通过类名来定义变量。不同的地方在于,通过结构体定义出来的变量还是叫做变量,而通过类定义出来的变量叫做对象(Object),这个过程叫做类的实例化,因此也称对象是类的一个实例(Instance)。 有些资料也将类的成员称为属性(Property),将类的成员函数称为方法(Instance) 在面向对象设计中,被定义为包含所有共性实体的Class类型,被称为基类。 C++的输入输出 C++中的输入输出可以看做是一连串的数据流,输入即可以视为从文件或者键盘中输入程序中的一串数据流,而输出可以视为从程序中输出一连串的数据流到显示屏或者文件中。实际编程中需要包含头文件iostreaminput output stream。cin 和cout是C++ 里面istream和ostream类的对象,是由标准库的开发者提前创建好的,而不是关键字。endl是end of line 的缩写。 #include<iostream> usingnamespace std; int main(){ int x; float y; cout<<"Pleaseinput an int number:"<<endl; cin>>x; cout<<"Theint number is x= "<<x<<endl; cout<<"Pleaseinput a float number:"<<endl; cin>>y; cout<<"Thefloat number is y= "<<y<<endl; return 0; }
C++的类 一个简单类的定义: class Student{ public: //成员变量 char *name; int age; float score; //成员函数 void say(){ cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl; } }; Student liLei; //创建对象
我们可以把Student看做一种新的数据类型,把liLei看做一个变量。创建对象的时候,class关键字可要可不要,出于习惯我们通常会省略class关键字。 补充知识点:栈(stack)和堆(heap)的区别,栈区一般有编译器自动释放,存放函数的参数值,局部变量的值,其操作方式类似于数据结构的栈。堆区一般由程序员分配释放,若程序员不释放的话,可能由操作系统回收,它与数据结构的堆是两回事,类似于数据结构的链表。 下面代码中创建的对象stu在栈上分配内存,需要使用&获取它的地址。pStu是一个指针,它指向Student类型的数据,也就是通过Student创建出来的对象。也可以在堆上创建对象,需要使用关键字new。在栈上创建的对象都有一个名字,比如stu,但是通过new创建的对象是匿名的,没办法直接使用,必须要用一个指针指向它,再借助指针访问它的成员变量或成员函数。通过对象名字访问成员使用点号.,通过对象指针访问成员使用箭头->,这和结构体指针类似。 Student stu; Student *pStu = &stu; Student *pStu = new Student;
C++类的成员函数 类的成员函数和普通函数一样,都有返回值和参数列表,它与一般函数的区别 是,它的作用范围由类决定,而普通函数是独立的,作用范围是全局的,或位于整个命名空间。在类体中直接定义函数时候,不需要在函数名前面加上类名。但当成员函数定义在类外时,就必须在函数名前面加上类名予以限定,::也称域解析符,用来连接类名和函数名。在函数类型名前加上关键字 inline 定义内联函数,目的是减少正常函数调用的开销,而直接应用函数体的编译代码代替函数调用,这称为函数体的内联扩展。它一般不影响函数名或其参数的作用域。(内联函数禁止使用递归(自己调用自己),防止无限编译) class Student{ public: //成员变量 char *name; int age; float score; //成员函数 void say(){ cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl; } }; class Student{ public: //成员变量 char *name; int age; float score; //成员函数 void say(); //函数声明 }; //函数定义 void Student::say(){ cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl; }
C++类的封装 C++通过public,protected,private三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的,受保护的,私有的,被称为成员访问限定符。所谓访问权限,就是你不能在外部使用该类的成员。类的声明和成员函数的定义都是类定义的一部分,在实际开发中,我们通常将类的声明放在头文件中,而将成员函数的定义放在源文件中。 类的成员变量是m_name,m_age,m_score被设置成private性质,在类的外部不能通过对象访问。成员函数setname(),setage(),setscore()被设置成public属性,是公有的,可以通过对象访问。声明为private和声明为public的成员的次序任意,如果两个都不写,就默认为private。 Private 关键字的作用在于更好地隐藏类的内部实现,该向外暴露的接口都声明为public,不希望外部知道,或者只在内部使用,或者对外部没有影响的成员,都建议声明为private。上面声明的三个成员函数用来设置成员变量的值,如果希望获取成员变量的值,可以再添加三个成员函数getname(),getage(),getscore()。 #include <iostream> using namespace std; //类的声明 class Student{ private: //私有的 char *m_name; int m_age; float m_score; public: //共有的 void setname(char *name); void setage(int age); void setscore(float score); void show(); }; //成员函数的定义 void Student::setname(char *name){ m_name = name; } void Student::setage(int age){ m_age = age; } void Student::setscore(float score){ m_score = score; } void Student::show(){ cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl; } int main(){ //在栈上创建对象 Student stu; stu.setname("小明"); stu.setage(15); stu.setscore(92.5f); stu.show(); //在堆上创建对象 Student *pstu = new Student; pstu -> setname("李华"); pstu -> setage(16); pstu -> setscore(96); pstu -> show();
return 0; }
C++的构造函数 使用构造函数可以简化公有的成员函数对私有的成员变量的赋值工作,在调用构造函数的时候需要同时传递实参,和普通的函数调用相似。在栈上创建对象时候,实参位于对象名后面。在堆上创建对象的时候,实参位于类名后面。 #include <iostream> using namespace std; class Student{ private: char *m_name; int m_age; float m_score; public: //声明构造函数 Student(char *name, int age, float score); //声明普通成员函数 void show(); }; //定义构造函数 Student::Student(char *name, int age, float score){ m_name = name; m_age = age; m_score = score; } //定义普通成员函数 void Student::show(){ cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl; } int main(){ //创建对象时向构造函数传参 Student stu("小明", 15, 92.5f); stu.show(); //创建对象时向构造函数传参 Student *pstu = new Student("李华", 16, 96); pstu -> show(); return 0; }
构造函数的目的是对成员变量进行初始化,为了达到这个目的,可以在构造函数的函数体中一一复制,也可以采用初始化列表。使用构造函数初始化列表并没有效率上的优势,仅仅是书写上的方便,尤其是成员变量较多的时候,这种方式简洁明了。 //采用初始化列表 Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ //TODO: }
C++的继承和派生 继承(inheritance)和派生(derive)是一个概念,只是站的角度不同。继承是儿子接受父亲的产业,而派生是父亲把产业传给儿子。被继承的类称为父类或基类,继承的类称为子类或派生类。基类成员在派生类中的访问权限不得高于继承方式制定的权限。比如public继承方式就基本不受影响,而private继承方式下的访问权限都变为不可见了。实际开发中我们一般使用public。 #include<iostream> using namespace std; //基类 Pelple class People{ public: void setname(char *name); void setage(int age); char *getname(); int getage(); private: char *m_name; int m_age; }; void People::setname(char *name){ m_name = name; } void People::setage(int age){ m_age = age; } char* People::getname(){ return m_name; } int People::getage(){ return m_age;} //派生类 Student class Student: public People{ public: void setscore(float score); float getscore(); private: float m_score; }; void Student::setscore(float score){ m_score = score; } float Student::getscore(){ return m_score; } int main(){ Student stu; stu.setname("小明"); stu.setage(16); stu.setscore(95.5f); cout<<stu.getname()<<"的年龄是 "<<stu.getage()<<",成绩是 "<<stu.getscore()<<endl; return 0; }
多继承即一个派生类可以有两个或多个基类,多继承容易让代码逻辑复杂,思路混乱,一直备受争议,中小型项目中较少使用。面对菱形继承,我们可以采用虚继承的方式,加上关键字virtual。 C++的多态 #include <iostream> using namespace std; //基类People class People{ public: People(char *name, int age); void display(); protected: char *m_name; int m_age; }; People::People(char *name, int age): m_name(name), m_age(age){} void People::display(){ cout<<m_name<<"今年"<<m_age<<"岁了,是个无业游民。"<<endl; } //派生类Teacher class Teacher: public People{ public: Teacher(char *name, int age, int salary); void display(); private: int m_salary; }; Teacher::Teacher(char *name, int age, int salary): People(name, age), m_salary(salary){} void Teacher::display(){ cout<<m_name<<"今年"<<m_age<<"岁了,是一名教师,每月有"<<m_salary<<"元的收入。"<<endl; } int main(){ People *p = new People("王志刚", 23); p -> display(); p = new Teacher("赵宏佳", 45, 8200); p -> display(); return 0; }
运行结果: 王志刚今年23岁了,是个无业游民。 赵宏佳今年45岁了,是个无业游民。 我们直观上认为,如果指针指向了派生类对象,那么久应该使用派生类的成员变量和成员函数,这符合人们的思维习惯。但是本例告诉我们,当基类指针p指向派生类Teacher的对象时,虽然使用了Teacher的成员变量,但是却没有使用它的成员函数,导致输出的结果不伦不类,不符合我们的预期。为了消除这种尴尬,让基类指针能够访问派生类的成员变量,C++增加了虚函数,只需要在函数声明前增加virtual关键字。换句话说,基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们称这种现象为多态(polymorphism)。 #include <iostream> using namespace std; //基类People class People{ public: People(char *name, int age); virtual void display(); //声明为虚函数 protected: char *m_name; int m_age; }; People::People(char *name, int age): m_name(name), m_age(age){} void People::display(){ cout<<m_name<<"今年"<<m_age<<"岁了,是个无业游民。"<<endl; } //派生类Teacher class Teacher: public People{ public: Teacher(char *name, int age, int salary); virtual void display(); //声明为虚函数 private: int m_salary; }; Teacher::Teacher(char *name, int age, int salary): People(name, age), m_salary(salary){} void Teacher::display(){ cout<<m_name<<"今年"<<m_age<<"岁了,是一名教师,每月有"<<m_salary<<"元的收入。"<<endl; } int main(){ People *p = new People("王志刚", 23); p -> display(); p = new Teacher("赵宏佳", 45, 8200); p -> display(); return 0; }
运行结果: 王志刚今年23岁了,是个无业游民。 赵宏佳今年45岁了,是一名教师,每月有8200元的收入。 文件夹过滤
使用beyond compare 过滤除.c 和.h的文件,百度没找到,我自己摸索的。 步骤1 打开beyond compare 选择sync BaseFolders 步骤2 选择源文件夹和目标文件夹
步骤3 选择过滤方案只保留.c和.h文件
步骤4 开始同步 步骤5 查看源文件夹和目标文件夹属性,可以看到子文件夹数目相同,文件数大大减少
这里记录一个Excel的问题,格式刷是一个好东西。 有一个单元格在有输入数据的时候,背景是白色的,删除单元格中的数据后背景变成了橙色。修改单元格填充颜色也没有用。这个时候,我唯一能想到的办法是格式刷。用空白单元格的格式覆盖这个有问题的单元格的格式。
|