欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Small Snapper C++ 快速入门学习笔记

最编程 2024-05-04 15:36:46
...

小甲鱼C++快速入门全套48节视频及配套PPT、配套所有源码和推荐C++学习电子书籍等C++资料已整理,请往链接( download.****.net/download/qq… 查看

目录:

**第一讲:C++语言与OO思想介绍
第二讲:从一个小程序说起
**作业1:整型数组求和
作业2:求带任意空格的输入整数之和

第三讲:输入输出方法
实例1:忽略输入字符串的前面部分字符输出
实例2:打印输入的一段文本,回车结束
实例3:打印输入的前20个字符
作业1:对3开方不同精度输出
作业2:对于输入的字符串,每次提取其四个字符,以不同输出宽度输出

第四讲:文件操作
实例1:文件读取(读取同一文件夹的test.txt文件内容)
实例2:将0-9写入到同一文件夹的test.txt文件
实例3:以添加形式将10-0写入test.txt文件
实例4:同时完成对test.txt的读写
作业:将text1.txt文件内容复制到text2.txt中

第五讲:输入输出小结
实例1:根据输入内容输出
实例2:摄氏、华氏温度转换

**第六讲:函数的重载
**实例1:改变同一函数的输入参数类型
作业:calc()传入不同数目的参数时,不同运算的运用
实例2:打印出用户输入的字符串
实例3:实例1的规范改进

第七讲:复杂的数据类型
第八讲:复杂的数据类型——指针
第九讲:复杂的数据类型——指针02
****实例1:通过指针形式修改变量值(指针的解引用)

**第十讲:复杂的数据类型——指针和数组
**实例1:数组元素地址打印
实例2:数组重载
实例3:泛型数组重载

**第十一讲:结构
**实例1:简单数据库读写
**第十二讲:传值、传址和传引用
**实例1:值传递
实例2:指针地址传递
实例3:两值互换
实例4:两值互换2
实例5:不用指针的两值交换

**第十三讲:联合、枚举和类型别名
**实例1:联合的应用
实例2:枚举的应用

**第十四节:对象
**实例1:对象应用造一辆车
**第十五讲:构造器和析构器
**实例1:构造器的运用
实例2:构造器与析构器的共同应用

**第十六讲:this指针和类的继承
**实例1:子类与基类的运用
**第十七讲:继承机制中的构造器和析构器
**实例1:构造器及其参数的继承应用
实例2:构造器与析构器的综合运用

**第十八讲:访问控制
**实例1:访问级别应用
**第十九讲:覆盖方法和重载方法
**实例1:覆盖应用
实例2:重载应用
实例3:子类内声明重载

**第二十讲:一种特殊的友情关系——友元关系
**实例1:友元关系访问保护量
**第二十一讲:静态属性和静态方法
**实例1:静态变量实例
**第二十二讲:静态属性和静态方法2
**实例1:this指针应用
**第二十三讲:虚方法
**实例:虚方法的运用
**第二十四讲:抽象方法抽象方法(abstract method,也可以成为纯虚函数)
**实例1:抽象方法应用
实例2:析构函数解析

**第二十五讲:运算符的重载
**实例1:复数加法
实例2:复数加法2
作业:分数加减乘除的操作符重载

**第二十六讲:运算符重载2
第二十七讲:运算符左移<<重载
**实例:左移操作符重载
**第二十八讲:多继承(multiple inheritance)
第二十九讲:虚继承
**实例:虚继承应用
**第三十讲:错误处理和调试
第三十一讲:错误处理与调试2
**实例:范围限制
第三十二讲:assert函数和捕获异常
****实例1:assert函数应用
实例2:捕获异常(try,catch,throw)

**第三十三讲:动态的内存管理
**实例:动态内存管理
**第三十四讲:动态数组
**实例:动态数组
**第三十五讲:从函数或方法返回内存
**实例1:函数或方法返回内存
实例2:函数指针

**第三十六讲:副本构造器
**实例1:带指针变量的等号重载
实例2:副本构造器

**第三十七讲:高级强制类型转换
**实例1:静态强制转换
实例2:动态强制转换

**第三十八讲:避免内存泄漏
第三十九讲:命名空间和模块化编程
**实例:头文件应用
**第四十讲:命名空间与模块化编程2
第四十一讲:命名空间
第四十二讲:链接和作用域
第四十三讲:链接和作用域2
第四十四讲:函数模板swap使用
**实例:函数模板
**第四十五讲:类模板
**实例:栈的出入栈
**第四十六讲:内联模板
**实例:栈
**第四十七讲:容器和算法
**实例:向量容器应用
**第四十八讲:向量和容器2
**实例:迭代器指针应用

 

第一讲:C++语言与OO思想介绍

OO思想:每个对象都是一个完整的独立的个体,由相关的属性和行为组合与外界分隔。其思想就是将一切事物都看做一个对象,由于一个再复杂的模型结构都是由千千万万个对象组成的。从而使程序员不再面对一个个函数与变量,而是放眼全局,面对一个个对象。

OO思想的特点:

                         1封装:把对象的属性和方法结合成一个独立的系统单位,并尽可能隐藏内部细节

 2抽象:对具体问题进行概括、对一类公共问题进行统一描述的过程

 3继承:子类对象拥有与其基类相同的全部属性和方法

 4多态:在基类定义的属性和行为被子类继承后可以具有不同的数据类型或者表现行为等特性

第二讲:从一个小程序说起

cout(cout << i表示变量i流向屏幕显示)是一个输出流对象,属于basic_ostream类的对象。ostream类在iostream头文件中定义。同理cin(回车后,键盘输入缓冲区内容流向cin流的内部缓冲区,cin >> xx操作便从这个缓冲区提取数据,即键盘输入流向程序)为输入流对象,

C++标准库所使用的所有标识符(即类、函数、对象等的名称)都是在一个特殊的名字空间(std)中来定义。

C++允许在程序的任意位置声明变量

作业1:整型数组求和

#include <iostream>  //iostream  C92 C99

using namespace std;//名字空间,cout与cin都在其里面

int addArray( int *array, int n );

int main()
{
int data[] = {0, 1, 2, 3, 4, 5,6, 7, 8, 9};
int size = sizeof(data) / sizeof(data[0]);

      std::cout << "结果是: " << addArray(data, size) << std::endl;//std:cout表示cout在std里面,类似结构体

      return 0;
}

int addArray( int *array, int n )
{
int sum = 0;
int i;

      for( i=0; i < n; i++ )
{
sum += *array++;
}

      return sum;
}

作业2:求带任意空格的输入整数之和

#include <iostream>  // 

using namespace std;//名字空间 

int main()
{
int sum=0;
int i;

cout<<"请输入一串整数和任意数目的空格:";

while(cin>>i)//正常输入时 
{
sum+=i;
while(cin.peek()==' ')//屏蔽空格  
{
cin.get();

if(cin.peek()=='\n')
{
break;//跳出while循环 
}
}

cout<<"结果是:"<<sum<<endl;

return 0;
}

第三讲:输入输出方法

实例1:忽略输入字符串的前面部分字符输出

#include <iostream>  // 

using namespace std;//名字空间 

int main()
{
char buf[20];//只能存放19个字符,因为字符串以0结尾 

cin.ignore(7);//忽略输入的前七个字符 
cin.getline(buf,10);//获取10个字符存放在buf中,默认字符串以0结尾 

cout<<buf<<endl;//endl表示清空缓存区 

return 0;
}

实例2:打印输入的一段文本,回车结束

#include <iostream>  // 

using namespace std;//名字空间 

int main()
{
char p;

cout<<"请输入一段文本:\n";

while(cin.peek()!='\n')//peek偷看输入的数据,不修改 
{
cout<<(p=cin.get());//cin.get表示获取输入的一个字符  
}
cout<<endl;//endl表示清空缓存区 

return 0;
}

实例3:打印输入的前20个字符

#include <iostream>  // 

using namespace std;//名字空间 

int main()
{
const int SIZE=50;
char buf[SIZE];

cout<<"请输入一段文本:";
cin.read(buf,20);//读取20个字符到buf缓冲区中 

cout<<"字符串收集到的字符数为:"<<cin.gcount()<<endl;//计算提取到的字符数 

cout<<"输入的文本信息是:";
cout.write(buf,20); //从缓冲区输出20个字符 

cout<<endl;//endl表示清空缓存区 

return 0;
}

作业1:对3开方不同精度输出

#include <iostream>  //
#include <math.h> 

using namespace std;//名字空间 

int main()
{
double result=sqrt(3.0);

cout<<"对3开方保留小数点后0~9位,结果如下:\n\n"<<result;

      for(int i=0;i<=9;i++)
{
cout.precision(i);
cout<<result<<endl;

cout<<"当前输出的精度为:"<<cout.precision()<<endl;          
return 0;
}

作业2:对于输入的字符串,每次提取其四个字符,以不同输出宽度输出

#include <iostream>  //
#include <math.h> 

using namespace std;//名字空间 

int main()
{
int width = 4;
char str[20];

cout<<"请输入一段文本:\n";
cin.width(5);//一次提取4个字符,因为最后有一个回车 

      while(cin >> str)
{
cout.width(width++);//设置不同的右对齐输出宽度 
cout<<str<<endl;
cin.width(5);

return 0;
}

第四讲:文件操作

ifream与ofream分别为文件读取类和文件写入类

实例1:文件读取(读取同一文件夹的test.txt文件内容)

#include <fstream>// 涉及到了文件流操作 
#include <iostream>

using namespace std;

int main()// in输入:读     out输出:写 
{
ifstream in;// 用ifstream(文件读取类)这个类定义in这个对象,所以in拥有了这个对象所有功能性质 

in.open( "test.txt" );// 打开这个文件 
if( !in )// 打开失败 
{
cerr << "打开文件失败" << endl;
return 0;
}

      char x;
while( in >> x )//文件in流到字符x中去,每次流一个字符 
{
cout << x;
}

      cout << endl;
in.close();//关闭文件 

      return 0;
}

实例2:将0-9写入到同一文件夹的test.txt文件

#include <fstream>//涉及到了文件流操作 
#include <iostream>

using namespace std;

int main()
{
ofstream out;//ofstream(文件输出类,写文件)

      out.open( "test.txt" );
if( !out )
{
cerr << "打开文件失败!" << endl;
return 0;
}

      for( int i=0; i < 10; i++ )
{
out << i;
}

out << endl;
out.close();

      return 0;
}

实例3:以添加形式将10-0写入test.txt文件

#include <fstream>
#include <iostream>

using namespace std;

int main()//ofstream 为构造函数 
{
ofstream out( "test.txt", ios::app );// app表示以添加形式(即不覆盖原数据)打开 

      if( !out )
{
cerr << "文件打开失败!" << endl;
return 0;
}

      for( int i=10; i > 0; i-- )
{
out << i;
}

      out << endl;
out.close();

      return 0;
}

实例4:同时完成对test.txt的读写

#include <fstream>
#include <iostream>

using namespace std;

int main()
{
fstream fp("test.txt", ios::in | ios::out );
if( !fp )
{
cerr << "打开文件失败!" << endl;
return 0;
}

      fp << "IloveFishc.com!IloveFishc.com!";

      static char str[100]; 

      fp.seekg(ios::beg); //使得文件指针指向文件头   ios::end则是文件尾。
fp >> str;
cout << str << endl;

      fp.close();

      return 0;
}

作业:将text1.txt文件内容复制到text2.txt中

#include <fstream>//涉及到了文件流操作 
#include <iostream>

using namespace std;

int main()
{
ifstream in;
ofstream out;
char x;
in.open("text1.txt");
out.open("text2.txt");
while(!in)
{
cout<<"源文件打开失败,请重新输入路径:";
return 0;
}
while(!out)
{
cout<<"目标文件失败,请重新输入路径:";
return 0;
}
while(in>>x)
{
out<<x;
}
out<<endl;
in.close();//关闭文件 
out.close();//关闭文件 
system("pause");
return 0;

}

第五讲:输入输出小结

实例1:根据输入内容输出

#include<iostream> 
using namespace std;//名字空间
int main()
{
char answer;

cout << "请问可以格式化您的硬盘吗?!【Y/N】" << "\n";
cin >> answer;

switch(answer)
{
case'Y':
case'y':
cout <<"随便格式化硬盘是不好的,会让妈妈骂的~"<<"\n";
break;
case'N':
case'n':
cout << "您的选择是明智的!" << "\n";
break;
default: 
cout << "您的输入不符合要求!!!" << "\n";
break;    
}
std::cin.ignore(100,'\n');//忽略带回车的100个输入字符 

std::cout << "输入任何字符结束程序!" << "\n";
std::cin.get();

return 0; 
}

实例2:摄氏、华氏温度转换

//温度转换  华氏温度 = 摄氏温度 * 9.0/5.0 + 32 
//const与define作用相同,都为定义常亮,但尽量用const 
#include <iostream>
using namespace std;
int main()
{
const unsigned short ADD_SUBTRACT = 32; 
const double RATI0 = 9.0 / 5.0;

double tempIn,tempOut;//输入输出数据 
char typeIn,typeOut;//输入输出类型(摄氏度F或华氏温度C) 

std::cout << "请亲们以【xx.x C】或者【xx.x F】格式输入一个温度:";
std::cin >> tempIn >> typeIn;
switch(typeIn)
{
case 'c':
case 'C':
tempOut = tempIn * RATI0 +32;
typeIn = 'C';
typeOut = 'F';
break;
case 'f':
case 'F':
tempOut = (tempIn - 32)/RATI0;
typeIn = 'F';
typeOut = 'C';
break;
default:
typeOut = 'E';
}  
if(typeOut != 'E')
{
cout <<"\n"<< tempIn << typeIn << " = " << tempOut << typeOut << "\n\n";
}
else
{
cout << "输入错误!\n"; 

}

cin.ignore(100,'\n');//忽略带回车的100个输入字符
std::cout << "输入任何字符结束程序!" << "\n";
std::cin.get();

return 0;

第六讲:函数的重载

函数重载:实质就是用同样的名字再定义一个有着不同参数类型及个数来实现不同操作的函数。

实例1:改变同一函数的输入参数类型

#include <iostream>

void convertTemperature(double tempIn, char typeIn);
void convertTemperature(int tempIn, char typeIn);

int main()
{
double tempIn;
int tempInInt;
char typeIn;

    std::cout << "请以【xx.x C】或【xx.x F】的形式输入温度: ";
std::cin >> tempIn >> typeIn;
std::cin.ignore(100, '\n');
std::cout << "\n";
convertTemperature(tempIn, typeIn);

    std::cout << "请以【xx C】或【xx F】的形式输入温度: ";
std::cin >> tempInInt >> typeIn;
std::cin.ignore(100, '\n');
std::cout << "\n";
convertTemperature(tempInInt, typeIn);

    return 0;
}

void convertTemperature(double tempIn, char typeIn)
{     
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0 / 5.0;

double tempOut;
char typeOut;      

switch( typeIn )
{
case 'C':
case 'c':
tempOut = (tempIn * RATIO) + ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;

      case 'F':
case 'f':
tempOut = (tempIn - ADD_SUBTRACT) / RATIO;
typeOut = 'C';
typeIn = 'F';
break;

      default:
typeOut = 'E';
break;                  
}

      if( typeOut != 'E' )
{
std::cout << tempIn << typeIn << " = " << tempOut << typeOut << "\n\n";
}
else
{
std::cout << "请按照给出格式输入!" << "\n\n";
}

      std::cout << "请输入任意字符结束!" << "\n";
std::cin.get();
}

void convertTemperature(int tempIn, char typeIn)
{     
const unsigned short ADD_SUBTRACT = 32;
const double RATIO = 9.0 / 5.0;

int tempOut;
char typeOut;      

switch( typeIn )
{
case 'C':
case 'c':
tempOut = (tempIn * RATIO) + ADD_SUBTRACT;
typeOut = 'F';
typeIn = 'C';
break;

      case 'F':
case 'f':
tempOut = (tempIn - ADD_SUBTRACT) / RATIO;
typeOut = 'C';
typeIn = 'F';
break;

      default:
typeOut = 'E';
break;                  
}

      if( typeOut != 'E' )
{
std::cout << tempIn << typeIn << " = " << tempOut << typeOut << "\n\n";
}
else
{
std::cout << "请按照给出格式输入!" << "\n\n";
}

      std::cout << "请输入任意字符结束!" << "\n";
std::cin.get();
}

作业:calc()传入不同数目的参数时,不同运算的运用

#include <iostream>

double calc(double tempIn);//计算该参数平方值 
double calc(double tempIn, double tempIn2);//计算两个参数的积 
double calc(double tempIn, double tempIn2, double tempIn3);//计算三个参数的和 

int main()
{
double tempIn,tempIn2,tempIn3;
int number; 
double tempOut;

    std::cout << "请输入数据个数: ";
std::cin >> number;

std::cout << "请以【xx xx】形式输入具体数据: ";  
switch(number)
{
case 1:
std::cin >> tempIn;
tempOut = calc(tempIn);
break;
case 2:
std::cin >> tempIn >> tempIn2;
tempOut = calc(tempIn, tempIn2);
break;
case 3:
std::cin >> tempIn >> tempIn2 >> tempIn3;
tempOut = calc(tempIn, tempIn2, tempIn3);
break;
default:
std::cout << "错误!";
break; 
}
std::cout << "计算结果为:" << tempOut << "\n";

std::cin.ignore(100, '\n');
std::cout << "\n";

    return 0;
}

double calc(double tempIn)
{
return tempIn*tempIn;
}

double calc(double tempIn, double tempIn2)
{
return tempIn*tempIn2;
}

double calc(double tempIn, double tempIn2, double tempIn3)
{
return (tempIn + tempIn2 + tempIn3);
}

第七讲:复杂的数据类型

数组:可以把许多个同类型的值存储在同一变量名下

实例1:输入的数据存储到数组中,并计算其和与平均值输出

#include <iostream>

using namespace std;//使用作用域 

int main()
{
int array[10];
int i;
int sum=0;
double average;

cout << "请输入10个整数!\n"; 
for(i=0;i<10;i++)
{
cout << "请输入第" << i+1 << "个整数:";
cin >> array[i];
sum+=array[i];
}
average = sum/10.0; 
cout << "和为:" << sum << "\n" << "平均值为:" << average << "\n";  

return 0;
}

实例2:打印出用户输入的字符串

#include <iostream>
#include <string>

using namespace std;

int main()
{
string str;
cout << "请输入一个字符串:";
getline(cin, str);//getline为获取一行数据  cin >> str使用时遇到空格便默认输入接收 
cout << str;

return 0; 

实例3:实例1的规范改进

#include <iostream>
//未完善 
using namespace std;//使用作用域 
//当输入错误时,cin会返回错误0 
#define ITEM 10
int main()
{
int array[ITEM];
int i;
int sum=0;
double average;

cout << "请输入" << ITEM << "个整数!\n"; 
for(i=0;i<ITEM;i++)
{
cout << "请输入第" << i+1 << "个整数:";
while(!(cin >> array[i])) //输入非法时是下一次输入时才进入循环 
{
cin.clear();//清楚不规范输入值 
cin.ignore(100,'\n');
cout << "\n请输入一个合法的值!";
cout << "\n请重新输入第" << i+1 << "个整数:\n"; 
cin >> array[i];
}
sum+=array[i];
}
average = (double)sum/ITEM; 
cout << "和为:" << sum << "\n" << "平均值为:" << average << "\n";  

return 0;
}

第八讲:复杂的数据类型——指针

小知识:程序以文件的形式存储在硬盘,但它们却是在计算机的内存中运行

                对于变量可以通过变量名与地址两种方式进行索引,变量的地址在程序执行期间是不会发生变换的

                地址是计算机内存中的某个位置;指针是专门用来存放地址的特殊类型变量

第九讲:复杂的数据类型——指针02

                指针的类型必须与由它保存其地址的变量的类型一致,当某个变量的地址给了指针p时,就可以通过*p(即表示该地址的数据)来对该变量数据进行操作

                一定要牢记一个事实:指针所保存的是内存中的一个地址,它并不保存指向的数据的值本身。因此务必确保指针对应一个已经存在的变量或者一块已经分配的内存            

               *有两种用途,一是创建指针: int *p = &a;   另外是解引用  *p = 123;

               c++允许多个指针指向同一个地址

               .void *则为“无类型指针”,可以指向任何数据类型。对一个无类型指针进行解引用前必须先将他转换为一个适当的数据类型。

实例1:通过指针形式修改变量值(指针的解引用)

#include <iostream>
using namespace std;

int main()
{
int a = 123;
float b = 3.14;
char c = 'c';
unsigned long d = 19880808;
string e = "I love FishC!";

cout << "a的值是:" << a << "\n";
cout << "b的值是:" << b << "\n";
cout << "c的值是:" << c << "\n";
cout << "d的值是:" << d << "\n";
cout << "e的值是:" << e << "\n\n";

int *aPointer = &a;
float *bPointer = &b;
char *cPointer = &c;
unsigned long *dPointer = &d;
string *ePointer = &e;

*aPointer = 456;
*bPointer = 4.13;
*cPointer = 'F';
*dPointer = 20190525;
*ePointer = "I love Beauty!";

cout << "a的值是:" << a << "\n";
cout << "b的值是:" << b << "\n";
cout << "c的值是:" << c << "\n";
cout << "d的值是:" << d << "\n";
cout << "e的值是:" << e << "\n\n";

}

第十讲:复杂的数据类型——指针和数组

计算机是把数组以一组连续的内存块保存的。

数组的第一个元素的地址为该数组的基地址。

实例1:数组元素地址打印

#include <iostream>

using namespace std;

int main()
{
const unsigned short ITEMS = 5;
int intArray[ITEMS] = {1,2,3,4,5};
char charArray[ITEMS] = {'F','i','s','h','C'};

int *intPtr = intArray;
char *charPtr = charArray;

cout << "整型数组输出:" << '\n';
for(int i=0;i < ITEMS; i++)
{
std::cout << *intPtr << " at " << (intPtr) << '\n';//用reinterpret_cast把指针类型强制转换为unsigned int
intPtr++;//地址加上以其所定义的类型所占的字节 


cout << "字符型数组输出:" << '\n';
for(int i=0;i < ITEMS; i++) 
{
cout << *charPtr << " at " << (charPtr) << '\n';
charPtr++;
}
return 0;

实例2:数组重载

#include <iostream>

using namespace std;

void print(int *pBegin,int *pEnd)
{
while(pBegin != pEnd)
{
cout << *pBegin;
++pBegin;//地址加1 
}
}

void print(char *pBegin,char *pEnd)
{
while(pBegin != pEnd)
{
cout << *pBegin;
++pBegin;//地址加1 
}

int main()
{
int num[5] = {0,1,2,3,4};
char name[5] = {'F','i','s','h','C'};

print(num,num + 5);
cout << '\n';
print(name,name + 5);
cout << '\n';

return 0;
}

实例3:泛型数组重载

#include <iostream>

using namespace std;

template <typename elemType>//将输入参数typename的类型赋值给elemType
void print(elemType *pBegin,elemType *pEnd)
{
while(pBegin != pEnd)
{
cout << *pBegin;
++pBegin;//地址加1 
}
}

int main()
{
int num[5] = {0,1,2,3,4};
char name[5] = {'F','i','s','h','C'};

print(num,num + 5);
cout << '\n';
print(name,name + 5);
cout << '\n';

return 0;
}

第十一讲:结构

结构是一种由程序员自己定义的、由其他变量类型组合而成的数据类型。其所能包含的变量的个数是没有限制的。

实例1:简单数据库读写


#include <iostream>
#include <fstream>  //文件操作 
#include <windows.h>        // 为了使用Sleep()函数 

struct FishOil
{
std::string name;
std::string uid;
char sex;
}; 

bool InitFishC();
bool ReadFishC(); 
void RecordFishC();
bool WriteFishC(FishOil *OilData);

int main()
{
int i;

InitFishC();  // 初始化数据。 
while( 1 )

std::cout << "请选择需要进行的操作: \n";
std::cout << "1. 打印数据到屏幕\n";
std::cout << "2. 录入数据\n"; 
std::cout << "3. 退出程序\n"; 
std::cin >> i;

switch( i )
{
case 1: 
if( ReadFishC() )
std::cout << "成功读取文件^_^\n\n";
else
std::cout << "读取文件失败T_T\n\n";
break;
case 2:
RecordFishC();
break;
case 3:
return 0;        
}
}

return 0;

}

bool InitFishC()
{
FishOil OilInit = {"小甲鱼", "fishc00001", 'M'};

        if( WriteFishC(&OilInit) == false )
std::cout << "初始化失败T_T\n";  

bool ReadFishC() //读文件 
{
std::string temp;
std::ifstream fileInput("FishC.txt");

if(  fileInput.is_open() )
{
std::cout << "\n正在输出记录数据...... ";
for( int i=0; i <= 100; i++ )      // 打印百分比 
{
std::cout.width(3);
std::cout << i << "%";
Sleep(50);
std::cout << "\b\b\b\b";
}
std::cout << "\n\n";

                std::cout << " 姓名 " << "  身份证  " << " 性别 " << "\n\n";

while( std::getline( fileInput, temp ) )
{
std::cout << temp << "   ";
std::cout << "\n";
}
std::cout << "\n\n";

return true;

else
return false;
}

void RecordFishC()//录入数据 
{
char goon, Save;
FishOil OilData;
FishOil *pOilData;

goon = 'Y';
while( 'Y' == goon )
{
std::cout << "请输入鱼C账号: ";
std::cin >> OilData.name;
std::cout << "请输入鱼C身份证:";
std::cin >> OilData.uid;
std::cout << "请输入性别:";
std::cin >> OilData.sex;

std::cout << "录入成功, 请问需要保存吗?(Y/N)";
std::cin >> Save;         
if( 'Y' == Save )
{
pOilData = &OilData;
if( WriteFishC( pOilData ) )
std::cout << "成功写入文件^_^\n";
else
std::cout << "写入文件失败T_T\n";        
}
else
{
return;
}

std::cout << "/n请问需要再次录入吗?(Y/N)";
std::cin >> goon; 
}
}

bool WriteFishC( FishOil *pOilData )//写文件 
{
std::ofstream fileOutput("FishC.txt", std::ios::app);  
// std::ios::app用来说明在老数据追加新数据 
if( fileOutput.is_open() )
{
fileOutput << pOilData->name << " ";
fileOutput << pOilData->uid << " ";
fileOutput << pOilData->sex << "\n";

fileOutput.close();
std::cout << "数据成功保存到FishC.txt\n\n";
return true; 

else
std::cout << "保存失败T_T\n";
return false;         
}

第十二讲:传值、传址和传引用

实例1:值传递

#include<iostream>

void changeAge(int age,int newAge); 
int main()
{
int age = 24;//定义一个age,占一处地址 
std::cout << "My age is " << age <<"\n";

changeAge(age,age + 1);

std::cout << "Now my age is " << age << "\n";

return 0;
}

void changeAge(int age,int newAge)//再定义一个age,占另一处地址 
{
age = newAge;
std::cout << "In this, my age is " << age << "\n"; 
}

绕开“值传递”问题的第一种方法是向函数传递变量的地址取代他的值。

实例2:指针地址传递

#include<iostream>

void changeAge(int *age,int newAge); 
int main()
{
int age = 24;//定义一个age,占一处地址 
std::cout << "My age is " << age <<"\n";

changeAge(&age,age + 1);

std::cout << "Now my age is " << age << "\n";

return 0;
}

void changeAge(int *age,int newAge)//再定义一个age,占另一处地址 
{
*age = newAge;
std::cout << "In this, my age is " << *age << "\n"; 
}

实例3:两值互换

#include<iostream>

void swap(int *x,int *y);
int main()
{
int x,y;

std::cout << "请输入两个不同的值:";
std::cin >> x >> y;

swap(&x,&y);

std::cout << "调换后输出:" << x << ' ' << y <<"\n\n"; 

}

void swap(int *x,int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}

实例4:两值互换2

#include<iostream>

void swap(int *x,int *y);
int main()
{
int x,y;

std::cout << "请输入两个不同的值:";
std::cin >> x >> y;

swap(&x,&y);

std::cout << "调换后输出:" << x << ' ' << y <<"\n\n"; 

}

void swap(int *x,int *y)
{
*x ^= *y;
*y = *x;
*x ^= *y;
}

实例5:不用指针的两值交换

#include <iostream> 

void swap(int &x,int &y);

int main()
{
int x,y;
std::cout << "请输入两个不同的值:";
std::cin >> x >> y;

swap(x,y);
std::cout << "调换后输出:" << x << ' ' << y << "\n\n";

return 0;
}

void swap(int &x,int &y)
{
int temp;
temp = x;
x = y;
y = temp;
}

第十三讲:联合、枚举和类型别名

联合(union)与结构有很多相似之处,联合也可以容纳多种不同类型的值,但是它每次只能储存这些值中的一个(即当我们已经给联合里的一个成员赋值后,再给另一个成员赋值时,将丢弃第一个成员的值)

实例1:联合的应用

#include <iostream>

union mima
{
unsigned long birthday;
unsigned short ssn;
const char *pet;//将pet声明为一个指向不变字符串的指针     
};

int main()
{
mima mima_1;

mima_1.birthday = 19970328;
std::cout << mima_1.birthday << "\n";

mima_1.pet = "Chaozai";//为字符串指针内的数据赋值 
std::cout << mima_1.pet << "\n";
std::cout << mima_1.birthday << "\n";//由于覆盖,将输出pet中字符串存储的地址 

return 0;
}

枚举(enum)类型用来创建一个可取值列表。枚举值不是字符串,编译器会按照各个枚举值在定义时出现的先后顺序把它们与0~n-1的整数(n是枚举值的总个数)分别关联起来。

实例2:枚举的应用

#include <iostream>

int main()
{
enum weekdays{Monday, Tuesday, Wednesday, Thursday, Friday};//编译后依次变为0、1、2、3、4 

weekdays today;

today = Monday;
std::cout << today << "\n";

today = Friday;
std::cout << today << "\n";

switch (today)
{
case Monday:
std::cout << "hello";
break;
case Tuesday:
std::cout << "yiwofeiye";
break;
default:
std::cout << "Goodbye";
break;
}
return 0; 

类型别名(typedef)可以为一个类型定义创建一个别名。例如:

定义typedef int* intPointer;后便可以使用intPointer myPointer;来定义整型指针。

第十四节:对象

对象本质上不过是一种新的数据类型。

类(class)是一个模型(就像是一张蓝图,它决定一个对象将拥有什么样的属性、功能等),且每个类跟变量一样都有一个名字。当我们为这个类创建实例的时候,也就是对象(类的具体化实现)。

类由变量(类里的变量称属性)和函数(类里的函数称方法)组成,对象将使用那些变量来存放信息,调用那些函数来完成操作。同理对象内部有变量和函数,而结构通常只由各种变量构成。

例如std::cout即为使用的是std类中的cout对象;std:string数据类型使用的是std类中的string对象

 

面相对象编程技术(object-oriented programming)可以说是面向过程技术(procedural programming)的替代品。

面向过程技术关注的是对数据进行处理的过程,面向对象(OOP技术)关注的是对数据进行怎样的处理。

实例1:对象应用造一辆车

#include <iostream>

#define FULL_GAS 85 

class Car//让我们来造辆车,定义类Car ,C++允许在类里面声明常量,但不允许对它进行赋值 
{
public:
std::string color;
std::string engine;
unsigned int gas_tank;//油缸 
unsigned int wheel;

void setColor(std::string col);
void setEngine(std::string eng);
void setWheel(unsigned int whe);
void filltank(int liter);//加油
int running(void);//动
void warning(void); 
};
void Car::setColor(std::string col) 
{
color = col;
}
void Car::setEngine(std::string eng)
{
engine = eng;
}
void Car::setWheel(unsigned int whe)
{
wheel = whe;

void Car::filltank(int liter)//函数(又称方法)的定义 
{
gas_tank += liter;
}
int Car::running(void)
{
std::cout << "我正在以120的时速往前移动。。。\n";
gas_tank--;
std::cout << "当前还剩 " << 100*gas_tank/FULL_GAS << "%" << "油量!\n";

return gas_tank; 

void Car::warning(void)
{
std::cout << "WARNING!!" << "\n还剩 " <<  100*gas_tank/FULL_GAS << "%" << "油量!\n";

int main()
{
char i;
Car mycar, car1;

mycar.setColor("WHITE");
mycar.setEngine("V8");
mycar.setWheel(4);

mycar.gas_tank = FULL_GAS;

while(mycar.running() )
{
if(mycar.gas_tank < 10)
{
mycar.warning();
std::cout << "请问是否需要加满油再行驶?(Y/N)\n";
std::cin >> i;
if( 'Y'== i || 'y' == i)
{
mycar.filltank(FULL_GAS); 
}
}

}   
return 0;
}

第十五讲:构造器和析构器


构造器和通常方法的主要区别:

1、构造器的名字必须和它所在类的名字一样  

2、系统在创建某个类的对象时会第一时间自动调用这个类的构造器  

3、构造器永远不会返回任何值

实例1:构造器的运用

#include <iostream>

#define FULL_GAS 85 

class Car//让我们来造辆车,定义类Car ,C++允许在类里面声明常量,但不允许对它进行赋值 
{
public:
std::string color;
std::string engine;
unsigned int gas_tank;//油缸 
unsigned int wheel;

Car(void);//类Car的构造函数,系统会自动调用
void setColor(std::string col);
void setEngine(std::string eng);
void setWheel(unsigned int whe);
void filltank(int liter);//加油
int running(void);//动
void warning(void); 
};
Car::Car(void)
{
color = "White";
engine = "V8";
wheel = 4;
gas_tank = FULL_GAS;

void Car::setColor(std::string col) 
{
color = col;
}
void Car::setEngine(std::string eng)
{
engine = eng;
}
void Car::setWheel(unsigned int whe)
{
wheel = whe;

void Car::filltank(int liter)//函数(又称方法)的定义 
{
gas_tank += liter;
}
int Car::running(void)
{
char i;

std::cout << "我正在以120的时速往前移动。。。\n";
gas_tank--;
std::cout << "当前还剩 " << 100*gas_tank/FULL_GAS << "%" << "油量!\n";

if(gas_tank < 10)
{
warning();
std::cout << "请问是否需要加满油再行驶?(Y/N)\n";
std::cin >> i;
if( 'Y'== i || 'y' == i)
{
filltank(FULL_GAS); 
}

if(gas_tank == 0)
{
std::cout << "抛瞄中。。。。。";
return 0;
}
}

return gas_tank; 

void Car::warning(void)
{
std::cout << "WARNING!!" << "\n还剩 " <<  100*gas_tank/FULL_GAS << "%" << "油量!\n";

int main()
{
Car mycar;

mycar.gas_tank = FULL_GAS;

while(mycar.running())//有油则继续跑,没有油则结束
{
;
}   
return 0;
}

在销毁一个对象时,系统会调用另一个特殊方法,即析构器。

一般来说,构造器用来完成事先的初始化和准备互作(申请分配内存);析构器用来完成事后所必须的清理工作(清理内存)

析构器不返回任何值,也不带参数

实例2:构造器与析构器的共同应用

#include <iostream>
#include <string>
#include <fstream>

class StoreQuote//定义类StoreQuote 
{
public:
std::string quote,speaker;
std::ofstream fileOutput;//定义文件对象fileOutput 

StoreQuote();//构造器 
~StoreQuote();//析构器

void inputQuote();//名言输入 
void inputSpeaker();//作者输入 
bool write();//写文件 
};

StoreQuote::StoreQuote()
{
fileOutput.open("test.txt", std::ios::app);//以附加(app)的形式打开文件 
}

StoreQuote::~StoreQuote()//关闭文件,释放内存 
{
fileOutput.close();
}

void StoreQuote::inputQuote()
{
std::getline(std::cin, quote);
}
void StoreQuote::inputSpeaker()
{
std::getline(std::cin, speaker);
}

bool StoreQuote::write()
{
if(fileOutput.is_open())//文件是否打开成功 
{
fileOutput << quote << "|" << speaker << "\n";//写入数据 
return true;
}
else
{
return false;
}
}

int main()
{
StoreQuote quote;//使用StoreQuote类定义一个对象quote 

std::cout << "请输入一句名言:\n";
quote.inputQuote();

std::cout << "请输入作者:\n";
quote.inputSpeaker();

if(quote.write())//文件是否写入成功 
{
std::cout << "成功写入文件"; 
}
else
{
std::cout << "写入文件失败"; 
return 1;
}
return 0;
}

第十六讲:this指针和类的继承

this指针指的是指向当前类生成的对象

继承机制使得程序员可以创建一个类的堆叠层次结构,每个子类均将继承在它的基类定义的方法和属性。

简单地说,就是通过继承机制,可以对现有的代码进行进一步扩展,并应用到新的程序中。

基类可以派生出其它的类,也称为父类或超类(如动物类)

子类是从基类派生出来的类(如乌龟类、猪类)

实例1:子类与基类的运用

#include <iostream>
#include <string>

class Animal//定义Animal类
{
public:
std::string mouth;
void eat();
void sleep();
void drool();//流鼻涕
};

class Pig:public Animal//类Pig继承于类Animal
{
public:
void climb();
};
class Turtle:public Animal//类Turtle继承于类Animal
{
public:
void swim();
};

void Animal::eat()//Animal类中的方法函数
{
std::cout << "I'm eatting!" << std::endl;
}
void Animal::sleep()
{
std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}
void Animal::drool()
{
std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
}
void Pig::climb()//类Pig中的climb方法函数
{
std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
}
void Turtle::swim()//类Turtle中的swim方法函数
{
std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
}
int main()
{
Pig pig;
Turtle turtle;//定义一个对象turtle

    pig.eat();
turtle.eat();
pig.climb();
turtle.swim();

    return 0; } 第十七讲:继承机制中的构造器和析构器

实例1:构造器及其参数的继承应用

#include <iostream>
#include <string>

class Animal//定义Animal类
{
public:
std::string mouth;
std::string name;

Animal(std::string theName);//类Animal的构造器 
void eat();
void sleep();
void drool();//流鼻涕
};
Animal::Animal(std::string theName)//类Animal构造器函数 
{
name = theName;
}

class Pig:public Animal//类Pig继承于类Animal
{
public:
Pig(std::string theName);//类Pig的构造器
void climb();
};
Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
{

class Turtle:public Animal//类Turtle继承于类Animal
{
public:
Turtle(std::string theName);//类Pig的构造器
void swim();
};
Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
{

}

void Animal::eat()//Animal类中的方法函数
{
std::cout << "I'm eatting!" << std::endl;
}
void Animal::sleep()
{
std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}
void Animal::drool()
{
std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
}

void Pig::climb()//类Pig中的climb方法函数
{
std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
}
void Turtle::swim()//类Turtle中的swim方法函数
{
std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
}
int main()
{
Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
Turtle turtle("小甲鱼");//定义一个对象turtle

std::cout << "这只猪的名字是:" << pig.name << std::endl;
std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 

    pig.eat();
turtle.eat();
pig.climb();
turtle.swim();

    return 0;
}

实例2:构造器与析构器的综合运用

#include <iostream>
#include <string>
//由于继承,编译后将首先调用基类构造器,然后调用子类构造器,然后运行其它程序;
//运行到程序末尾时,先调用子类析构器,让后调用基类析构器。
class BaseClass//定义基类BaseClass 
{
public:
BaseClass();//构造器
~BaseClass();//析构器

void doSomething();    
};  

class SubClass : public BaseClass定义子类SubClass,类SubClass继承于类BaseClass 
{
public:
SubClass();
~SubClass();
};

BaseClass::BaseClass()//类BaseClass构造器函数 
{
std::cout << "进入基类构造器。。。\n";
std::cout << "我在基类构造器里边干了某些事。。。\n\n";
}

BaseClass::~BaseClass()//类BaseClass析构器函数 
{
std::cout << "进入基类析构器。。。\n";
std::cout << "我在基类析构器里边干了某些事。。。\n\n";
}
void BaseClass::doSomething()//基类的doSomething函数 
{
std::cout << "我干了某些事。。。\n\n";

SubClass::SubClass()//子类SubClass的构造函数 
{
std::cout << "进入子类构造器。。。\n";
std::cout << "我在子类构造器里面还干了某些事。。。\n\n";
}
SubClass::~SubClass()//子类SubClass的析构函数 
{
std::cout << "进入子类析构器。。。\n";
std::cout << "我在子类析构器里面还干了某些事。。。\n\n";
}
int main()
{
SubClass subclass;
subclass.doSomething();

std::cout << "完事,收工!\n"; 
return 0;
}

第十八讲:访问控制

访问控制:C++提供用来保护(保护意思是对谁可以调用某个方法和访问某一个属性加上一个限制)类里的方法和属性的手段

实例1:访问级别应用

//级别            允许谁来访问
//public           任何代码 
//protected        这个类本身和它的子类 
//private          只有这个类本身
#include <iostream>
#include <string>

class Animal//定义Animal类
{
public:
std::string mouth;
//std::string name;

Animal(std::string theName);//类Animal的构造器 
void eat();
void sleep();
void drool();//流鼻涕
protected:
std::string name;
};
Animal::Animal(std::string theName)//类Animal构造器函数 
{
name = theName;
}

class Pig:public Animal//类Pig继承于类Animal
{
public:
Pig(std::string theName);//类Pig的构造器
void climb();
};
Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
{

class Turtle:public Animal//类Turtle继承于类Animal
{
public:
Turtle(std::string theName);//类Pig的构造器
void swim();
};
Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
{

}

void Animal::eat()//Animal类中的方法函数
{
std::cout << "I'm eatting!" << std::endl;
}
void Animal::sleep()
{
std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}
void Animal::drool()
{
std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
}

void Pig::climb()//类Pig中的climb方法函数
{
std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
}
void Turtle::swim()//类Turtle中的swim方法函数
{
std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
}
int main()
{
Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
Turtle turtle("小甲鱼");//定义一个对象turtle

//pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 

std::cout << "这只猪的名字是:" << pig.name << std::endl;
std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 

    pig.eat();
turtle.eat();
pig.climb();
turtle.swim();

    return 0;
}

使用private的好处:可以只修改某个类的内部实现,而不必重新修改整个程序。因为其他代码根本就访问不到private保护的内容

在同一个类中可以使用多个public:,private和protected:语句,但最好把你的元素集中到一个地方,可读性会更好。

protected

把基类的访问级别改为protected,如果原来是public的话。这将使得这个子类外部的代码无法通过子类去访问基类中的public

private

是在告诉编译器从基类继承来的每一个成员都当做private来对待,这意味着只有这个子类可以使用它从基类继承来的元素。

第十九讲:覆盖方法和重载方法

覆盖是指派生类函数覆盖基类函数(函数名字参数相同且基类函数必须有virtual关键字)

以上学习可知可以通过创建新的子类来重用现有的代码(继承)

当我们需要在基类里提供一个通用的函数,但在它的某个子类里需要修改这个方法的实现,覆盖(overriding)就可以做到。

实例1:覆盖应用

//级别            允许谁来访问
//public           任何代码 
//protected        这个类本身和它的子类 
//private          只有这个类本身
#include <iostream>
#include <string>

class Animal//定义Animal类
{
public:
std::string mouth;
//std::string name;

Animal(std::string theName);//类Animal的构造器 
void eat();
void sleep();
void drool();//流鼻涕
protected:
std::string name;
};
Animal::Animal(std::string theName)//类Animal构造器函数 
{
name = theName;
}

class Pig:public Animal//类Pig继承于类Animal
{
public:
Pig(std::string theName);//类Pig的构造器
void climb();
void eat();   //new  再一次声明,以便原函数可以覆盖修改 
};
Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
{

class Turtle:public Animal//类Turtle继承于类Animal
{
public:
Turtle(std::string theName);//类Pig的构造器
void swim();
void eat();   //new  再一次声明,以便原函数可以覆盖修改 
};
Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
{

}

void Animal::eat()//Animal类中的方法函数
{
std::cout << "I'm eatting!" << std::endl;
}
void Animal::sleep()
{
std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}
void Animal::drool()
{
std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
}

void Pig::climb()//类Pig中的climb方法函数
{
std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
}
void Turtle::swim()//类Turtle中的swim方法函数
{
std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
}
void Pig::eat()//重新声明eat方法 
{
Animal::eat();//可省去 
std::cout << "我在吃鱼\n\n" << std::endl;
}
void Turtle::eat()//重新声明eat方法 
{
Animal::eat();//可省去
std::cout << "我正在吃东坡肉!\n\n" << std::endl;
}


int main()
{
Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
Turtle turtle("小甲鱼");//定义一个对象turtle

//pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 

//  std::cout << "这只猪的名字是:" << pig.name << std::endl;        
//    std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 

    pig.eat();
turtle.eat();
pig.climb();
turtle.swim();

    return 0;
}

重载机制使你可以定义多个同名的方法(函数),只是它们的输入参数必须不同。(因为编译器是依靠不同的输入参数来区分不同的方法)

实例2:重载应用

//级别            允许谁来访问
//public           任何代码 
//protected        这个类本身和它的子类 
//private          只有这个类本身
#include <iostream>
#include <string>

class Animal//定义Animal类
{
public:
std::string mouth;
//std::string name;

Animal(std::string theName);//类Animal的构造器 
void eat();
void eat(int eatCount); 
void sleep();
void drool();//流鼻涕
protected:
std::string name;
};
Animal::Animal(std::string theName)//类Animal构造器函数 
{
name = theName;
}

class Pig:public Animal//类Pig继承于类Animal
{
public:
Pig(std::string theName);//类Pig的构造器
void climb();
};
Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
{

class Turtle:public Animal//类Turtle继承于类Animal
{
public:
Turtle(std::string theName);//类Pig的构造器
void swim();
};
Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
{

}

void Animal::eat()//Animal类中的方法函数
{
std::cout << "I'm eatting!" << std::endl;
}
void Animal::eat(int eatCount)
{
std::cout << "我吃了" << eatCount << "碗馄饨!\n";
}
void Animal::sleep()
{
std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}
void Animal::drool()
{
std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
}

void Pig::climb()//类Pig中的climb方法函数
{
std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
}
void Turtle::swim()//类Turtle中的swim方法函数
{
std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
}

int main()
{
Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
Turtle turtle("小甲鱼");//定义一个对象turtle

//pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 
//  std::cout << "这只猪的名字是:" << pig.name << std::endl;        
//    std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 

    pig.eat();
turtle.eat();

pig.eat(15);
pig.climb();
turtle.swim();

    return 0;
}
在对方法进行覆盖(注意区分覆盖和重载)时,一定要看仔细,因为只要声明的输入参数和返回值与原来的不一致,你编写出来的就将是一个重载的方法而不是覆盖方法。

实例3:子类内声明重载

//级别            允许谁来访问
//public           任何代码 
//protected        这个类本身和它的子类 
//private          只有这个类本身
#include <iostream>
#include <string>

class Animal//定义Animal类,基类 
{
public:
std::string mouth;
//std::string name;

Animal(std::string theName);//类Animal的构造器 
void eat();

void sleep();
void drool();//流鼻涕
protected:
std::string name;
};
Animal::Animal(std::string theName)//类Animal构造器函数 
{
name = theName;
}

class Pig:public Animal//类Pig继承于类Animal,子类 
{
public:
Pig(std::string theName);//类Pig的构造器
void climb();
void eat(int eatCount);//重载 
};
Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
{

class Turtle:public Animal//类Turtle继承于类Animal
{
public:
Turtle(std::string theName);//类Pig的构造器
void swim();
};
Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
{

}

void Animal::eat()//Animal类中的方法函数
{
std::cout << "I'm eatting!" << std::endl;
}

void Animal::sleep()
{
std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}
void Animal::drool()
{
std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
}

void Pig::climb()//类Pig中的climb方法函数
{
std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
}
void Pig::eat(int eatCount)
{
std::cout << "我吃了" << eatCount << "碗馄饨!\n";
}

void Turtle::swim()//类Turtle中的swim方法函数
{
std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
}

int main()
{
Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
Turtle turtle("小甲鱼");//定义一个对象turtle

//pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 
//  std::cout << "这只猪的名字是:" << pig.name <<

上一篇: Centos 7.7 安装和配置教程

下一篇: