VC++ 基础知识 总结

1) C++中,结构体内部可以有函数,C语言中不能有函数。

2) C++中,结构体和类可以通用,结构体是一种特殊的类,特殊性体现在它是struct定义的类。

3) 结构体,缺省的成员访问类型是public,类的是private。

4) 类的一个实例就是一个对象。

5) 面向过程和面向对象的比较:比如,打开一个收音机。面向过程的实现方式是实现一个打开函数,收音机是以参数的方式传进来,然后打开对应的收音机。面向对象的实现方式是实现一个收音机类,收音机本身具有了打开功能,我们只需去调用打开功能就可以了。

6) 构造函数最重要的作用是创建对象本身。

7) 当定义一个对象时,构造函数也执行了,里面可以对对象内部数据成员进行初始化。

8) 定义一个类时,会占用存储空间,这个空间就是构造函数的所占据的。

9) C++规定,每个类必须有一个构造函数,没有构造函数,就不能创建任何对象。

10)             如果用户没有创建构造函数,那么编译器会提供一个默认的构造函数。它只负责创建对象,而不做任何的初始化工作。

11)             析构函数,用来对对象的内存释放。

12)             构造函数和析构函数是由系统调用的。

13)             构造函数可以带参数,析构函数不能有参数。比如,在构造函数中申请的堆内存,可以在构造函数中进行释放。

14)             构造函数可以有多个,这样的方式较重载。


15)             函数的重载。构成的条件:函数的参数类型、参数个数不同,才能构成函数的重载。

16)             不能构成重载的函数:

                        i.             第一种情况  1)void output(); 2)int output();

                      ii.             第二种情况  1)void output(int a ,int b=5); 2)void output(int a);

17)             下面这段程序结果为多少呢?

#include<iostream.h>
class Point
{
       public:
       int x;
       int y;
       Point()
       {
              x=5;
              y=6;
       }
       Point(int a,int b)
       {
              x=a;
              y=b;
       }
       ~Point()
       {
 
       }
       void output()
       {
              cout<<x<<endl<<y<<endl;
       }
       void output(int x,int y)
       {
              x=x;
              y=y;
       }
};
 
void main()
{
       Point pt(3,3);
       pt.output(5,5);
       pt.output();
}

上面的程序输出为3,3。主要是因为变量的可见性问题。

如果我想输出5,5。应该这样去写代码: 

void output(int x,int y)

       {

              this->x=x;

              this->y=y;     

}

18)             This指针式一个隐含指针,它是指向对象本身,代码对象的地址。

19)             继承的方式:public  private  protected

20)             Protected:在基类中定义的protected方式。子类中可以使用,但是外面不能使用(比如main函数中)。

21)             Public:任何地方都可以被访问。

22)             Private:子类中都不能被访问。

23)             类的继承访问特性

基类的访问特性

类的继承特性

子类的访问特性

Public

Protected

Private

Public

Public

Protected

No access

Public

Protected

Private

Protected

Protected

Protected

No access

Public

Protected

Private

Private

Private

Private

No access

24)             子类继承父类。子类和父类都有构造函数和析构函数。当定义一个子类时,先调用父类的构造函数,再调用子类的构造函数;继而,先调用子类的析构函数,再调用父类的析构函数。总之,其调用顺序是相反的。

如下面代码所示:

#include <iostream.h>
class Animal
{
public:
       Animal()
       {
              cout<<"Animalconstruct"<<endl;
       }
       ~Animal()
       {
              cout<<"animaldeconstruct"<<endl;
       }
       voideat()
       {
              cout<<"animaleat"<<endl;
       }
 
       voidSleep()
       {
              cout<<"animalsleep"<<endl;
       }
 
       voidbreathe()
       {
              cout<<"animalbreathe"<<endl;
       }
};
class Fish : public Animal
{
public:
       Fish()
       {
              cout<<"fishconstruct"<<endl;
       }
       ~Fish()
       {
              cout<<"fishreconstruct"<<endl;
       }
};
 
void main()
{
       Fishfh;
}

输出结果:

25)             子类中常量的初始化

class Fish : public Animal
{
public:
       Fish():Animal(400,300),a(1)//下面常量的初始化
       {
              cout<<"fishconstruct"<<endl;
       }
       ~Fish()
       {
              cout<<"fishreconstruct"<<endl;
       }
private:
       constint a;
};

26)             函数的覆盖:发生在父类与子类之间的。

27)             函数的重载是发生在一个类之间的。


#include <iostream.h>
class Animal
{
public:
       Animal(intheight,int weight)
       {
              cout<<"Animalconstruct"<<endl;
       }
       ~Animal()
       {
              cout<<"animaldeconstruct"<<endl;
       }
       voideat()
       {
              cout<<"animaleat"<<endl;
       }
 
       voidSleep()
       {
              cout<<"animalsleep"<<endl;
       }
 
       voidbreathe()//不是虚函数
       {
              cout<<"animalbreathe"<<endl;
       }
};
class Fish : public Animal
{
public:
       Fish():Animal(400,300),a(1)
       {
              cout<<"fishconstruct"<<endl;
       }
       ~Fish()
       {
              cout<<"fishdeconstruct"<<endl;
       }
       void breathe()//函数覆盖
       {
              Animal::breathe();//也有父类的方法
              cout<<"fishbubble"<<endl;
       }
private:
       constint a;
};
void fn(Animal *pAn)
{
       pAn->breathe();
}
void main()
{
       Fishfh;
       Animal*pAn;
       pAn=&fh;//类型转换。但是animal和fish的this指针都指向相同的地址。fish和animal的存储空间模型是一致的。但是fish会被截取掉。
       fn(pAn);
       //fh.breathe();
}

输出结果:


当把父类的breathe方法前面加上virtual时,就会输出”fish bubble”。这就是所为的多态。如下图所示:


28)             多态性:当C++编译器在编译的时候,发现Animal类的breathe函数是虚函数,这个时候C++就会采用迟绑定的技术,在运行时,依据对象的类型(在我的程序中,我们传递的Fish类对象的地址)来确定调用的哪一个函数,这种能力就叫做C++的多态性。

29)             如果不加virtual,这个时候的breathe函数在编译的时候就已经绑定,如果加上virtual变成虚函数,breathe函数在运行的时候绑定,也就是迟绑定。

30)             Virtual函数总结一句话:子类有的,先调用子类的,子类没有的就调用父类的。

31)             纯虚函数是没有函数体的,如:virtual void breathe()=0;。这样的类是抽象类,它是不能实例化对象的,也就不能派生其他类。除非,你把这个纯虚函数实例化。比如,子类的fish中,你实例化了breathe函数:

       void breathe()//函数覆盖

       {

              cout<<"fishbubble"<<endl;

       }

如下面的代码:

#include <iostream.h>
class Animal
{
public:
       Animal(intheight,int weight)
       {
              cout<<"Animalconstruct"<<endl;
       }
       ~Animal()
       {
              cout<<"animaldeconstruct"<<endl;
       }
       voideat()
       {
              cout<<"animaleat"<<endl;
       }
 
       voidSleep()
       {
              cout<<"animalsleep"<<endl;
       }
 
       virtualvoid breathe()=0;
};
class Fish : public Animal
{
public:
       Fish():Animal(400,300),a(1)
       {
              cout<<"fishconstruct"<<endl;
       }
       ~Fish()
       {
              cout<<"fishdeconstruct"<<endl;
       }
       voidbreathe()//函数覆盖
       {
              //Animal::breathe();//也有父类的方法
              cout<<"fishbubble"<<endl;
       }
private:
       constint a;
};
void fn(Animal *pAn)
{
       pAn->breathe();
}
void main()
{
       Fishfh;
       Animal*pAn;
       pAn=&fh;//类型转换。但是animal和fish的this指针都指向相同的地址。fish和animal的存储空间模型是一致的。但是fish会被截取掉。
       fn(pAn);
       //fh.breathe();
}

32)             引用:实际上就是变量的别名。

33)             引用和指针变量的内存模型:


指针需要内存空间,引用不需要占据内存。

34)             引用一般用于函数传参,还有就是可读性更强一些。

35)             比如定义一个函数,去交换两个变量的值。

int change(int &a,int &b)
{
 
}
void main()
{
       intx=3;
       inty=4;
       change(x,y);//这里告诉你,x和y就是用来交换的。
}

上面这段代码要比指针的书写要清楚些。

int change(int *pA,int*pB)
{
 
}
void main()
{
       int x=3;
       int y=4;
       change(&x,&y);/这样的话,会让人少许有些误解。
}

36)             有些时候,可以这样去编写代码:

class Animal
{
public:
       Animal(intheight,int weight)
       {
              cout<<"Animalconstruct"<<endl;
       }
       ~Animal()
       {
              cout<<"animaldeconstruct"<<endl;
       }
       voideat();
 
       voidSleep()
       {
              cout<<"animalsleep"<<endl;
       }
 
       virtualvoid breathe()=0;
};
void Animal::eat()
{
       cout<<"animaleat"<<endl;
}

37)             防止类的重复定义问题,如下面代码所示:

class Point
{
 
};
class Point
{
 
};
 
void main()
{
       Pointpt;
}

这时候就会有错误:

这个时候,我们加上预编译指令就可以解决这个问题。

#ifndef POINT_H_H  //定义宏,一般用大写

#define POINT_H_H

…….

#endif

避免重复包含。

#ifndef POINT_H_H  //定义宏,一般用大写
#define POINT_H_H
class Point
{
 
};
#endif
 
#ifndef POINT_H_H
#define POINT_H_H
class Point
{
 
};
#endif
 
void main()
{
       Pointpt;
}

38)             编译过程,工程目录及代码如下:


编译过程如下:


欢迎读者批评,指正。     By  刘洼村

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值