c++优于c在于:封装性(Encapsulation)、继承性(Inheritance)、多态性(Polymorphism)
在C语言中,结构体内不能包含函数;c++结构体可以包含函数。
结构体与类:
结构体默认情况下,其成员是公有(public)的;类默认情况下,其成员是私有(private)的。
“类的实例” 和 “类的对象” 是同一个概念;对象是可以销毁的,但类(抽象的概念)是不能被销毁的。
构造、析构函数:
构造函数的作用是对对想本省做初始化工作,也就是给用户提供初始化类中成员变量的一种方式。
如果一个类中没有定义任何的构造函数,那么c++编译器在某些情况下会为该类提供一个默认的构造函数,这个默认的构造函数是一个不带参数的构造函数。只有一个类中定义了一个构造函数,不管这个构造函数是否是带参数的构造函数,c++编译器就不再提供默认的构造函数。也就是说:如果为一个类定义了一个待参数的构造函数,还想要无参数的构造函数,则必须自己定义。
析构函数不允许待参数,并且一个类中只能有一个析构函数。
函数的重载:
重载构成的条件:函数的参数类型、参数个数不同,才能构成函数的重载。函数的重载发生在同一个类中。
以下情况不能构成函数的重载:
对于第一种情况,当程序调用output()函数时,会出现错误。 注意:只有函数的返回类型不同是不能构成函数的重载的。第一种情况:(1)void output(); (2)int output(); 第二种情况;(1)void output(int a, int b=5); (2)void output(int a);
对于第二种情况,当程序调用output(5)时,也会出现错误。 在函数重载时,要注意函数带有默认参数的这种情况。
this指针:
this指针是一个隐含的指针,它是指向对象本身的,代表了对象的地址。所有对数据成员的访问都隐含地被加上了前缀this->;例如x=0;等价于this->x = 0;
类的继承:
在子类中调用父类的带参数的构造函数。
#include<iostream>
class animal
{
public:
animal(int height, int weight)
{
cout<<"animak construct"<<endl;
}
...
};
class fish:public animal
{
public:
fish():animal(400, 300) //此处如果没有(:animal(400, 300))程序将会不能运行,why?
{
cout<<"fish constrct"<<endl;
}
...
};
void main ()
{
fish fh;
}
虚函数与多态性、纯虚函数:如果在定义派生类时没有指定如何继承访问权限,则默认为private。
用virtual申明的函数叫虚函数。
c++的多态性:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将根据对象的实际类型来调用相应的函数。(如果对象类型是派生类,则调用派生类的函数;如果对象类型是基类,则调用基类的函数) 此处涉及c++的迟绑定技术 late binding(有virtual)、早绑定技术 early binding(无virtual)。
纯虚函数是指被表明为不具体实现的虚成员函数。凡是含有春旭函数的类叫做抽象类。该类不能声明对象,只是作为基类为派生类服务,在派生类中必须完全实现基类的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。
注意:c++的多态性是有虚函数来实现的,而不是纯虚函数。
函数覆盖(override):
构成函数覆盖的条件为:
*基类函数必须是虚函数(使用virtual关键字进行声明)。
*发生覆盖的两个函数要分别位于派生类和基类中。
*函数名称和参数列表必须完全相同。
由于c++的多态性是通过虚函数来实现的,所以函数的覆盖总是和多态关联在一起。在函数覆盖的情况下,编译器会在运行时根据对象的实际类型来确定要调用的函数。
函数隐藏:
指派生类中具有与基类同名的函数(不考虑参数列表是否相同),从而在派生类中隐藏了基类的同名函数。
class Base
{
public:
virtual void fn();
};
class Derived : public Base
{
public:
void fn(int );
};
class Drived2 : public Derived
{
public:
void fn();
};
函数的重载、覆盖、隐藏的区别:
重载:函数的参数个数、参数类型至少有一个不相同,且在同一个类中。(参数个数和参数类型相同,但是返回类型不同,这不是函数重载,这时函数调用时,会出现问题)函数重载只看参数个数和参数类型,不看返回值类型;如果只是返回值不同的函数那就不是重载函数。
覆盖:基类的函数必须是虚函数、不再同一个类中(分别位于基类和派生类中)、函数名称和参数列表必须完全相同
隐藏:不再同一个类中分别位于基类和派生类)
区分 覆盖 和 隐藏 :函数的覆盖是发生在派生类与基类之间,两个函数必须完全相同,并且都是虚函数。那么不属于这种情况的,就是隐藏了。有virtual的情况:派生类的函数与基类的函数完全相同(函数名和参数列表都相同),此时基类被隐藏。
派生类的函数与与基类的函数同名,但参数列表不同。此时基类是否声明virtual,此时基类都将被隐藏。
引用:
引用就是一个变量的别名,它需要用另一个变量或对象来初始化自身。
int a = 5; int &b = a; //用&表示申明一个引用,引用必须在申明时进行初始化。
c++程序编译链接的原理与过程: