VC++(二)掌握C++

2016-11-15  本文已影响0人  侧漏的少年

如果一个类没有定义任何的构造函数,那么编译器只会在以下三种情况,才会提供默认的构造函数。
1、如果类有虚拟成员函数或者虚拟继承父类(即有虚拟基类时);
2、如果类有基类的构造函数(可以是用户定义的,也可以是编译器提供的默认构造函数);
3、在类的所有非静态的对象数据成员,他们所属的类中有构造函数(可以是用户定义的,也可以是编译器提供的默认构造函数)
析构函数只能有一个,且不允许带任何参数在函数重载时,要注意函数带有默认参数的情况

父类构造函数、子类构造函数、子类析构函数、父类析构函数

class animal
{
public:
    animal(int height, int weight)
    {
    }
}
class fish
{
public:
    fish()::animal(400, 300)
    {
    }
}fish fh; 先调用父类带两个参数的构造函数,然后调用子类不带参数的构造函数

class point
{
public:
    point()::x(0), y(0) //一种初始化的方式
private:
    int x;
    int y;
}

public 定义的成员可以在任何地方被访问
protected 定义的成员只能在该类及其子类中访问
private 定义的成员只能在该类自身中访问
基类中的private成员不能被派生类访问,因此,private成员不能被派生类所继承

举例说明:
class animal
{
public:
    int publicMember;
protected:
    int protectedMember;
private:
    int privateMember;
}am;

class fish :public animal
{
}fh;

int main()
{
    fh.publicMember = 1; //OK
    fh.protectedMember = 1; //ERROR
    fh.privateMember = 1; //ERROR
    return 0;
}

class fish :private animal
{
}fh;

int main()
{
    fh.publicMember = 1; //OK
    return 0;
}
animal::publicMember”不可访问,因为“fish”使用“protected”从“animal”继承

总结一下:

class animal
{   
public: 
    void eat()  
    {                   
        cout << "animal eat";           
    }
    void sleep()            
    {           
        cout << "animal sleep";                         
    }
            
    virtual void breathe()               
    {           
        cout << "animal breathe";           
    }
}; 
class fish :public animal
{
public:
    void breathe()
    {
        cout << "fish bubble"; 
    }
}           
void fn(animal pAn)
{
    pAn->breathe(); 
}
void main()
{
    animal pAn; 
    fish fh; 
    pAn = &fh; 
    fn(pAn); 
}

基类中void breathe()加virtual 不加virtual的区别

不加virtual时,输出的是animal:
C++编译器将fh进行了类型转换,此时编译器认为pAn保存的就是animal对象的地址。调的当然是animal。
用virtual关键字声明的函数叫做虚函数。
C++的多态性用一句话概括就是:在基类的函数前加virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。
也就是说,多态性是按照对象的实际类型来运行的。
纯虚函数:
virtual void breathe() = 0;
含有纯虚函数的类叫做抽象类。
抽象类不能声明对象。
派生类中必须完全实现纯虚函数。否则派生类也是抽象类,不能实例化。
无论该覆盖定义是否有virtual关键字,该函数都是虚函数。

函数的覆盖:

1、基类函数必须是虚函数
2、发生覆盖的两个函数分别位于派生类和基类中
3、函数名称与参数列表必须完全相同

函数的隐藏两种情况:

1、派生类的函数和基类的函数完全相同,只是基类的函数没有virtual
2、派生类的函数与基类的函数同名,但参数列表不一样。不管基类的函数有没有virtual,基类的函数都将被隐藏。重载发生在一个类里面。
列表不一样就隐藏了、没有虚函数的事也隐藏了。
列表一样,有虚函数叫覆盖。
记住:函数覆盖,参数列表一样。
记住一句话:函数的覆盖是发生在派生类与基类之间,两个函数必须完全相同,并且都是虚函数,不属于这种情况的就是隐藏了。
覆盖了就不显示了,隐藏了还可以显示。

引用:

引用就是一个变量的别名
int a = 5;
int &b = a; //引用在声明时必须初始化。
引用一旦初始化,它就代表了一块特定的内存,不能再代表其他的内存。
指针是地址。指针变量要存储地址值,因此要占用存储空间。我们可以随时修改指针变量所保存的地址值,从而指向其他的内存。
设计习惯以及头文件重复包含的问题。
<> 和 "" 的区别。<> 和 "" 表示编译器在搜索头文件时的顺序不同。
<> 表示 系统目录、PATH环境变量列出的目录,不搜索当前目录。
"" 当前目录、系统目录、PATH环境变量列出的目录。

条件预处理指令

#ifndef ANIMAL_H_H
#define ANIMAL_H_H

VC++ 程序编译链接的原理与过程

C++对工程中的三个源文件单独进行编译。编译时,先由预处理器对预处理指令进行处理,在内存中输出翻译单元。编译器接受预处理器的输出。将源代码转换成包含机器语言指令的三个目标文件(obj)。接下来链接器将目标文件和标准类库一起链接生成exe文件。

上一篇 下一篇

猜你喜欢

热点阅读