1.面向对象编程的三大特点:封装、继承、多态
2.C++中若不指定类中成员的访问权限默认就是private的(class默认是private的,struct默认是public的)。
3.C++规范中类的名字的首字母应该大写。
4.C++中的this是个指针,指向当前类或对象。(注意C++中this是指针,通过this->member访问成员,而Java中的this不是指针,通过this.member访问成员)
5.C++中的就近原则
当传参数名和类的成员名是一样的话,使用的就是参数名,因为比较近。
6.C++中类中"public:"下面的都是public属性的成员,而Java中的类的每个函数前都要加权限修饰。
7.C++和Javac程序对比
/*This_test.java*/ class Person { String name; public void setName(String name) { this.name = name; System.out.println("name="+this.name); } }; /*这里写不写";"都行*/ /*注意是这个类中包含main()和注意格式*/ public class This_test { public static void main(String args[]) { /* 1.这里直接Person person;来定义对象不行,必须要new Person(),若是有参构造函数()里还需要加参数。 * 2.java中没有指针,C++中的char * 这里要换成String。 * 3.C++中的this是指针,通过this->访问成员,Java中通过.来访问成员。 */ Person person = new Person();//new Person("mmmm"); C++中只有定义指针时才是这样的,eg Person *p1 = new Person("Zhangshan", 10); person.setName("ZhangShan"); } };
/*cpp_this.cpp*/ #include <stdio.h> class Person { const char *name; public: void setName(const char *name) { this->name = name; /*the type of this is "Person* const"*/ printf("name=%s ", this->name); } }; /这里像结构体一样需要有“;”,但是namespace的{}后写不写都行/ int main() { Person person1; /*使用无参构造函数或有参Person person1("Zhangsan"); 这里不需要像Java语言必须去new一个对象*/ person1.setName("SunFaliang"); }
8.在类外实现类的函数,需要像C语言中声明格式一样在类中声明,然后在类外通过:“返回类型 类名::函数名(参数)”,通过命名空间引用也是使用"::"
9.没有使用命名空间的话,一个源文件要使用一个类,只需要包含这个类的声明的头文件即可。
10.using(非using namespace)后面跟的是对象,而不是命名空间,eg: using P1;报错,using P1::Person;正确(namespace P1{...})。
using P1::Person;表示把P1::Person放到global namespace中,然后就可以直接通过Person代表P1::Person
还可以吧using放到具体函数的内部,eg: 在函数内部使用using P1::Person;就是将P1::Person放到函数内部的local namespace中,
那么此时这个using只在此函数内部有效。
11.还有一种用法:using namespace P1; 表示把P1命名空间中的所有类和函数都导入进来。
using是一个一个地导入,using namespace是把整个命名空间的内容都导入进来。
12.若两个命名空间都定义了同样的函数,而且使用中使用using namespace同时导入了这两命名空间,只要不使用这个函数,也是没有问题的,
也就是说只有使用时链接有冲突了才编译报错。
13.#include <iostream>并且指定std命名空间后就可以使用cout<<进行打印,
using namespace std; cout<<XXX 或 std::cout<<XXX
14.引用,int& b = a; b是a的引用,也称为是a的别名,和a使用相同的地址。引用相当于一个常指针,在定义时必须初始化,eg. int &b; 编译是会报错的。
被引用的对象一定是要有实体的,例如作为非函数参数时int &b = 1; 编译时也会报错的。
15.当时const引用可以使用常量进行初始化,b放入符号表,没有实体,但是在编译时发现有强制取其地址,有会给它分配地址空间
const int &b = 1;
int *p = &b; //error: invalid conversion from ‘const int*’ to ‘int*’
int *p = (int *)&b; //ok
16.构造函数
与类同名,无返回类型,eg Person([参数])
Person per("ZhangSan", 10); //定义一个对象并使用2个参数的构造函数
Person per; //定义一个对象并使用无参数的构造函数
Person per(); //定义一个函数,返回Person ############################################
Person *p1 = new Person();
Person *p2 = new Person; //和上面一样都会调用无参构造函数来初始化对象
Person *p3 = new Person[4]; //指向一个数组,都调用无参构造函数。
Person *p4 = new Person("Zhangshan", 19);
使用完后,delete p1; delete []p3; 注意销毁的也是一个数组。
若是使用new获取的Person对象,没有使用delete释放,就算是整个进程执行结束,也不会调用析构函数,此时操作系统会帮我们释放分配的内存,可以使用free -m查看"free"栏。
17.析构函数
格式:~类名() 无论有多少个构造函数都只能有1个析构函数,而且这个析构函数还是没有参数的。
18.函数内部定义的对象在函数执行完后就会调用析构函数进行释放,但是函数内部new出来的对象是需要手动delete进行释放的。
19.下面代码,若name=NULL, 程序打印完“name= ”就死了!!!!为什么 ?????
cout << "name= " << name << ", age= " << age << ", work= " << work << endl;
20.拷贝构造函数和默认拷贝构造函数
C++编译器会为我们提供默认的什么都不做的无参构造函数和析构函数和默认的仅仅是值拷贝的拷贝构造函数。
一旦用户自己提供了构造函数,编译器提供的无参构造函数就不复存在了。因此定义了有参构造函数有时候还需要定义一个无参构造函数。
eg:定义自己的拷贝构造函数:
Person(Person &per) { cout << "Person(Person &per)" <<endl; this->name = new char[strlen(per.name) + 1]; memcpy(this->name, per.name, strlen(per.name)); this->name[strlen(per.name)] = '