VS2010 C++ MFC框架学习笔记4 - C++面向对象编程基础2
2015-06-09 16:30
821 查看
跟着教材《Visual C++ 2010 MFC 编程入门》.pdf 学习了2周,感觉有些基础的概念不太清楚,所以找出网易学堂的VC++课程进行学习http://tech.163.com/special/0009159F/vc.html
===========================================
[第二课 C++经典语法与应用 类的编写与应用]
===========================================
构造函数:采用类的方式来保证它的唯一性,取个类名,没有返回值,对类里的变量进行初始化。
析构函数:回收内存,没有返回,没有参数。
例:
上例中,出现了两个Point()构造函数,这种情况称为函数的重载:函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。参考:http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html
this指针是一个隐含的,指向对象本身,代表对象地址的指针;一个类所有的对象调用的成员函数都是同一代码段,如何区分不同对象但是同一类下的成员函数的执行呢?其实,成员函数除了接受参数外,还接受了一个对象的地址,这个地址被一个隐含的形参this指针所获取,等同于执行 this = &pt. 所有对数据成员的访问都隐含地被加上前缀this->
这里有个继承的权限叠加后,对method的最终对外访问权限的判定问题:
基类method的权限: 子类的继承特性: 最终对外访问特性:
------------------
构造函数的访问顺序
父类{
父类的构造函数(){
指令1;
}
~父类的构造函数(){
指令2;
}
}
子类:public 父类{ //继承
子类的构造函数(){
指令3;
}
~子类的构造函数(){
指令4;
}
}
main(){
子类.子类obj;
}
====执行结果:====
指令1;
指令3;
指令4;
指令2;
--------
如果父类的构造函数带参数,而子类不带,则子构造函数:
Fish():Animal(400,300){
}
========================
完整代码:
函数的覆盖:
发生在父类和子类之间的,父类下有个method_name(){},子类下也有个同名method_name(){},则子类的obj优先执行子类的函数/method
但是,如果又要用父类的method,则使用两个冒号来作为作用域标识符,例:
—————
| Animal |
—————
| Fish |
—————
如果要根据不同的类型(Animal or Fish)来调用不同类(Animal or Fish)下的函数,则可利用C++的多态性,在Animal的breathe()前加个virtual,将之定义为“虚函数”,让C++编译器作一个 late binding迟绑定。就可以了:
此时,再运行 fn(pAn) ,如果子类中有 breathe,则就会调用子类Fish中的breathe,如果没有,再调用Animal中的breathe
纯虚函数:
让父类只有操作名称,而没有具体的操作内容;让派生类在继承时候再具体地给出它的定义。
在不确定这种行为具体表现形式,而这种行为又是必须的,就可以在基类中以这种纯虚函数来。
C++中的引用:
把工程文件按.h & .cpp来管理:
.h 文件用于类的声明;
.cpp文件用于类的定义。
这里,Fish是继承于Animal的类,则include""的顺序要注意:
一个进一步的模型是:
也就是说,在main.cpp中include了Animal.h & Fish.h; 在Fish.h & Animal.cpp中,include"Animal.h" ; 在Fish.cpp中 include“Fish.h”
这里会有一个错误:因为main.cpp引用了Animal.h,同时main.cpp引用了Fish.h,而Fish.h再次引用了Animal.h,所以会报Animal.h中的类被重复定义。怎么办呢?使用预编译命令: #ifndef #def #endif
===========================================
[第二课 C++经典语法与应用 类的编写与应用]
===========================================
构造函数:采用类的方式来保证它的唯一性,取个类名,没有返回值,对类里的变量进行初始化。
析构函数:回收内存,没有返回,没有参数。
例:
#include<iostream> using namespace std; class Point{ public: int x; int y; Point(){ //构造函数,同,类名 x = 0; y = 0; } Point(int a, int b){ //构造函数,带参 x = a; y = b; } ~Point(){ //析构函数,取反符号+类名 } void output(){ cout<<x<<endl<<y<<endl; } void output(int x, int y){ this->x = x; //this point, 指向对象 this->y = y; } }; void main(){ Point pt(3,3); pt.output(5,5); pt.output(); }
上例中,出现了两个Point()构造函数,这种情况称为函数的重载:函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。参考:http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html
this指针是一个隐含的,指向对象本身,代表对象地址的指针;一个类所有的对象调用的成员函数都是同一代码段,如何区分不同对象但是同一类下的成员函数的执行呢?其实,成员函数除了接受参数外,还接受了一个对象的地址,这个地址被一个隐含的形参this指针所获取,等同于执行 this = &pt. 所有对数据成员的访问都隐含地被加上前缀this->
继承:
====================public; protected; private在继承中,对method的保护权限区别: 》public 是外部Y访问,子类Y访问 》protected 是外部N访问,子类Y访问 》private 是外部N访问,子类N访问如:#include<iostream> using namespace std; class Animal{ public: void eat(){ cout<<"animal eat"<<endl; } protected: void sleep(){ cout<<"animal sleep"<<endl; } private: void breathe(){ cout<<"animal breathe"<<endl; } }; class Fish : public Animal{ //子类的继承特性:这里是public式继承 void test(){ sleep(); //protected,子类中可以访问 //breathe();//private,子类都不能access } }; void main(){ Animal an; an.eat(); Fish fh; //fh.sleep();//protected, cannot access }
这里有个继承的权限叠加后,对method的最终对外访问权限的判定问题:
基类method的权限: 子类的继承特性: 最终对外访问特性:
基类method权限 | 类继承特性 | 子类的访问特性 |
Public Protected Private | Public | Public Protected No Access |
Public Protected Private | Protected | Protected Protected No Access |
Public Protected Private | Private | Private Private No Access |
构造函数的访问顺序
父类{
父类的构造函数(){
指令1;
}
~父类的构造函数(){
指令2;
}
}
子类:public 父类{ //继承
子类的构造函数(){
指令3;
}
~子类的构造函数(){
指令4;
}
}
main(){
子类.子类obj;
}
====执行结果:====
指令1;
指令3;
指令4;
指令2;
--------
如果父类的构造函数带参数,而子类不带,则子构造函数:
Fish():Animal(400,300){
}
========================
完整代码:
#include<iostream> using namespace std; class Animal{ public: Animal(int x, int y){ cout << "animal construct"<<endl; cout << x <<endl; cout << y <<endl; } void eat(){ cout<<"animal eat"<<endl; } protected: void sleep(){ cout<<"animal sleep"<<endl; } private: void breathe(){ cout<<"animal breathe"<<endl; } }; class Fish : public Animal{ public: Fish():Animal(300,400),a(11){ cout<<"fish construct"<<endl; cout<<a<<endl; } void test(){ sleep(); //protected,子类中可以访问 //breathe();//private,子类都不能access } private: const int a; }; void main(){ //Animal an; //an.eat(); Fish fh; //fh.sleep();//protected, cannot access getchar(); }
函数的覆盖:
发生在父类和子类之间的,父类下有个method_name(){},子类下也有个同名method_name(){},则子类的obj优先执行子类的函数/method但是,如果又要用父类的method,则使用两个冒号来作为作用域标识符,例:
class Fish : public Animal{ public: Fish(){ } void breathe(){ Animal::breathe(); //此处就是调父类的breathe()来 cout<<"fish bubble"<<endl; } };
C++继承的多态性:
void fn(Animal *pAn){ //有一个全局函数,输入Animal指针,找指针下的breathe()方法进行执行。 pAn->breathe(); } void main(){ Fish fh; //obj Declare Animal *pAn; //pointer Declare pAn = &fh; //赋值 fh(pAn); //调用 } //因为Fish是Animal的子类, //目测会调用Fish的breathe()函数来执行, //但是却执行了Animal类下的breathe()原因就是Fish和Animal是共用的一个内存起始地址。如下:
—————
| Animal |
—————
| Fish |
—————
如果要根据不同的类型(Animal or Fish)来调用不同类(Animal or Fish)下的函数,则可利用C++的多态性,在Animal的breathe()前加个virtual,将之定义为“虚函数”,让C++编译器作一个 late binding迟绑定。就可以了:
virtual void breathe(){ cout<<"Animal breathe"<<endl; }
此时,再运行 fn(pAn) ,如果子类中有 breathe,则就会调用子类Fish中的breathe,如果没有,再调用Animal中的breathe
纯虚函数:
让父类只有操作名称,而没有具体的操作内容;让派生类在继承时候再具体地给出它的定义。
Animal 下: virtual void breathe() = 0;
Fish 下: void breathe(){ cout <<"fish bubble..."<<endl ;}
在不确定这种行为具体表现形式,而这种行为又是必须的,就可以在基类中以这种纯虚函数来。
C++中的引用:
把工程文件按.h & .cpp来管理:.h 文件用于类的声明;
.cpp文件用于类的定义。
这里,Fish是继承于Animal的类,则include""的顺序要注意:
一个进一步的模型是:
也就是说,在main.cpp中include了Animal.h & Fish.h; 在Fish.h & Animal.cpp中,include"Animal.h" ; 在Fish.cpp中 include“Fish.h”
这里会有一个错误:因为main.cpp引用了Animal.h,同时main.cpp引用了Fish.h,而Fish.h再次引用了Animal.h,所以会报Animal.h中的类被重复定义。怎么办呢?使用预编译命令: #ifndef #def #endif
使用预编译命令
main.cpp引用了Animal.h,然后main.cpp引用了Fish.h,而Fish.h再次引用了Animal.h,所以会报Animal.h中的类被重复定义。怎么办呢?使用预编译命令: #ifndef #def #endif
//File: Animal.h //Declare the Animal class and the functions // #ifndef ANIMAL_H_H //用预编译指令符防止类的重复编译错误: if not define #define ANIMAL_H_H //用预编译指令符防止类的重复编译错误: define class Animal{ public: Animal(int height, int weight);//构造函数 void eat();// void sleep();// virtual void breathe();//virtual }; #endif //用预编译指令符防止类的重复编译错误: end if
VC++编译链接过程
先对cpp文件进行编译,编程成obj文件,h头文件不参与编译。最后进行链接。相关文章推荐
- C语言 链表反向打印与反转
- C++——vector操作
- 有用的C/C++网站
- C语言 二叉查找树相关算法
- C++析构函数
- c++ --> const关键字总结
- C++9.7、9.8 容器适配器----queue、stack
- 使用C++实现简单二叉树
- VC++ 字符串赋值例子(2)
- 【Divided Two】cpp
- ###《More Effective C++》- 基础议题
- Trie树
- 线表的c语言实现
- C++ 智能指针
- 统计字符串的某一子串在字符串中的出现次数(C语言实现)
- c 封装类,模范类
- VC++ 字符串赋值例子
- “HEAP CORRUPTION DETECTED”错误原因与解决
- vc++ PushBack 和 Assign 的示例
- 命令行解析器