Unit 1
C++对C的扩展
-------------------------------------------------------------------------
new
int *p = new int(7);
p指向int型四个字节的空间,被赋值为7.
delete p;
char *p=new char [10];
则是指向10个字节的空间。
delete 【】p;
内联函数
默认参数,可以不传。(在声明中确定默认值,不要在定义的时候)
默认值,是从右到左给默认的比如
int maxValue(int a,int b,int c)
要想给a默认值,就必须先给bc默认值。从右向左依次给默认参数。
函数重载
相同的函数名,不同的函数参数和类型。
* 二义性。
int maxValue(int a,int b = 7);
int maxValue(int a );
当主函数中出现
maxValue(5);时,不知道该调用哪个。
(注意函数默认值和函数重载同时使用时出现的问题)
Unit 2
面向对象
-------------------------------------------------------------------------
类
默认的成员变量都是私有的。
this->age
函数定义
void Person::setAge(int age)
{
this->age=age;
}
实践过程中出现了build失败的情况,原因是codeblock必须在同一个工程中才能进行链接编译。
Unit 3
成员函数
------------------------------------------------------------------------
常成员函数:
这个函数不能修改当前类里面的成员变量。当在.h里定义
int getAge() const;
时这时候在实现里面,也要写上const。 这是编译级限定。
为什么呢:
调用的时候比较安全。
*但是,如果这个常成员函数返回的是指针类型,就不安全了,得到指针的人完全可以拿指针来改变成员变量的值,这个时候就要把指针也定义成const。如
const char * getAge () const;这个时候,如果在主程序里char * p =per.getAge();就又不对了。通过强转可以进行赋值,但是还是const,不能修改成员变量的值。
只要你不改成员变量,就应该把它声明成const。
构造函数:
对象分配内存之后立即调用构造函数
Unit 4
内存管理
------------------------------------------------------------------------
析构函数:
对象内存被释放之前,调用析构。
~Person()不返回任何值,也没有任何参数,不能被重载。
实现
Person::~Person()
{
...
}
栈分配:
Person per = Person();
or
Person per;
堆分配:
Person *per= new Person();
per->info();
delete per();
动态分配内存:
int main(void)
{
Person *p=new Person( );
}
Person::Person( )
{
name=new char [255];
strcpy(name,"Hello World");
}
造成了内存泄露
需要在析构函数中释放
Person::~Person()
{
delete [] name;
}
如果在构造中打开了文件,在析构中关闭文件。
析构调用时机:
Person *p =new Person();
内存释放之前调用。
Person per;
main函数结束之后,出栈时调用。
Unit 5
内存管理
------------------------------------------------------------------------
拷贝构造函数:
*设置器:
如果想从外部设置类中name 的内容,可在类中定义一个
void setName (const char *name)
{
strcpy(this->name,name);
}
不能用
this name=(char *)name;
因为如果外部的name 在外部被释放掉的话,我们将保留不到name的值。所以用strcpy是最合适的。
*如果在主函数中:
Person per =Person();
Person per1=per;
// Person per1(per);
则会调用两次析构,会把name delete两次。
用一个对象初始化另一个对象时。要调用拷贝构造。
Person::Person (const Person &per)
{
/*系统默认实现是this -> name=name;
this->..........
这样是有问题的。*/
//手动修改
this->name = new char [255];
strcpy(this->name,per.name);
this->age=per.age;
this->sex=per.sex;
}
成员变量带指针,而且给这个指针分配内存时,需要重新实现拷贝构造函数.
操作符重载:
Person per =Person();
Person per1=Person;
per1=per;
这样不会调用拷贝构造!又出问题了!内存泄露,过度释放。
解决:
重新实现赋值操作符
声明Person &operator=(const Person & right)
实现Person &Person ::operator(const Person &right)
{
//系统实现是完全赋值 return *this;
//手动修改
// this->name = new c
har [255];
strcpy(this->name,right.name);
this->age=right.age;
this->sex=right.sex;
}
有问题!
原先右值已经new char [255],操作符重载时不要再new255了!
也可以根据现有的字符串,删除原来的内存,开辟新的内存。
拷贝构造是在创建一个新对象。操作符重载时对象已经存在。
Unit 6
继承
------------------------------------------------------------------------
class Student : public Person
{
...
}
指出继承方式。
调用子类的构造时,先构造父类,再构造子类
子类若有与父类同名的函数,会默认覆盖父类的函数。
子类没有父类的私有访问权限,虽然空间可以同样的开辟。可以在子类中调用父类的方法,要加父类的域作用符。
Unit 7
多态
------------------------------------------------------------------------
构造顺序:
父类,数据成员对象,子类
析构:
子类,成员对象,父类。
虚成员函数:
多态。
*父类类型的指针,调用子类的对象
void sayhi(Person *per)
{
per->info();
}
或者
Person *per=&stu;
per->info();
都会打印出父类的信息。(无法实现多态性)
这时候把父类的info改为 virtual void info( ) const;
// 为什么要有多态性:游戏中,(植物僵尸)攻击方法,利用子弹父类的指针,拿到子类的信息。
纯虚函数:
virtual void print( ) const=0;
这个方法不需要再实现了。子类来实现。包含纯虚函数的类是抽象类,不能实例化。
Unit 8
设计模式
------------------------------------------------------------------------