//二进制文件:变换第一个字节
#include <iostream>
#include <stdexcept>
#include <string>
#include <fstream>
using namespace std;
class test
{
private:
fstream f;
string s;
string::size_type n;
char c;
public:
test()
{
f.open("test1.exe",ios::in|ios::out|ios::binary);
if(!f)
{
cout<<"file error!"<<endl;
}
}
void turn1()
{
f.seekg(0,ios::end);
n=f.tellg();
s.resize(n);
f.seekg(0,ios::beg);//回到字符串的首位来读取
f.read((char*)s.c_str(),n);
s[0]=s[0]+5;//将第一个字节的asc码值加5
// s[0]=s[0]-5;
f.seekp(0,ios::beg);//回到字符串的首位来输入
f.write((char*)s.c_str(),n);
}
void turn2()
{
f.seekg(0,ios::beg);
f.read(&c,1);//读取字符串的0位开始的第一个字节(包括第0位)
c=c+5
// c=c-5;
f.seekp(0,ios::beg);
f.write(&c,1);
}
~test()
{
f.close();
}
};
int main()
{
test t;
t.turn1();
return 0;
}
#include <iostream>
#include <string>
using namespace std;
template<class T>//模板语句
T add(T a,T b)//T在这里代替int、double一类
{
return a+b;
}
int main()
{
cout<<add<int>(1,2)<<endl;
cout<<add<double>(1.5,2.3)<<endl;
return 0;
}
//=======函数模板========
#include <iostream>
using namespace std;
template <class T>//模板语句
void Swap(T& a,T& b)//注意:swap与库函数重名
{
T temp;
temp=a;
a=b;
b=temp;
}//交换的作用
int main()
{
int a1=10,b1=20;
cout<<"a1="<<a1<<endl;
cout<<"b1="<<b1<<endl;
cout<<"--------swap---------"<<endl;
Swap<int>(a1,b1);
cout<<"a1="<<a1<<endl;
cout<<"b1="<<b1<<endl;
return 0;
}
//函数模板
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template<class T>
T str2T(string s)
{
stringstream ss;
T temp;
ss<<s;
ss>>temp;
return temp;
}//转换字符的类型
int main()
{
string s="1.5";
double d=str2T<double>(s);//在这里将字符串s转换成了double类型
d=d*d;
cout<<d<<endl;
return 0;
}
//=======类模板========
#include <iostream>
#include <typeinfo>
#include <string>
#include <sstream>
using namespace std;
template <class T>//模板语句
class test
{
private:
T a,b;
public:
test(T aa,T bb)
{
a=aa;
b=bb;
}
//注意:参数不能是(string s),要与a、b的类型T匹配
int str2num(T s)
{
int temp;
stringstream ss;
ss<<s;
ss>>temp;
return temp;
}//在这里将字符串的类型转换成int
void add()
{
if(typeid(T)==typeid(int))//判断模板参数的类型
//typeid 运算符用来获取一个表达式的类型信息
{
cout<<a+b<<endl;
}
if(typeid(T)==typeid(string))//判断模板参数的类型
{
cout<<str2num(a)+str2num(b)<<endl;
}
}
};
int main()
{
test <int> t1(1,2);//注意:多了"<int>"一节,是类型实参
t1.add();
//==================
test <string> t2("10","20");//注意:多了"<string>"一节,是类型实参
t2.add();
return 0;
}
//=======命名空间========
#include <iostream>
using namespace std;
namespace ns1
{
class test
{
private:
int m;
public:
test(int mm)
{
m=mm;
}
void output()
{
cout<<m*m<<endl;
}
};
}
namespace ns2
{
class test
{
private:
int m;
public:
test(int mm)
{
m=mm;
}
void output()
{
cout<<m*m<<endl;
}
};
}
int main()
{
ns1::test t1(10);
ns2::test t2(20);
t1.output();
t2.output();
return 0;
}
命名空间:
假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。
同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。
因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。
具体知识点见:https://www.runoob.com/cplusplus/cpp-namespaces.html
//=======虚函数========
#include <iostream>
using namespace std;
class A
{
protected:
int m;
public:
A(int mm)
{
m=mm;
}
virtual void output()//这里为虚函数
{
cout<<"m="<<m<<endl;
}
};
class B:public A
{
protected:
int n;
public:
B(int mm,int nn):A(mm)
{
n=nn;
}
virtual void output()//这里为虚函数
{
cout<<"n="<<n<<endl;
}
};
int main()
{
A a(10);
B b(20,30);
A* p;//这里写成B* p结果也一样
p=&b;
p->output();//输出的结果是n=30
return 0;
}
若将p=&b改成p=&a,则输出的结果为:n=10。
虚函数:
C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。
具体知识点见:https://blog.csdn.net/haoel/article/details/1948051/
//异常处理:手工抛出异常信息
#include <iostream>
#include <stdexcept>
using namespace std;
class test
{
private:
double m,n;
public:
test(double mm,double nn)
{
m=mm;n=nn;
}
void ave() throw(int)
{
if(n>1)
cout<<m/n<<endl;
else if(n==1)
throw 1;
else if(n==0)
throw 0;
}
};
int main()
{
test t1(10,6),t2(10,1),t3(10,0);
try
{
t1.ave();
t2.ave();
t3.ave();
}
catch(int n)
{
if(n==1)
cout<<"devided by 1!"<<endl;
else if(n==0)
cout<<"devided by 0!"<<endl;
}
return 0;
}
运行的结果:
为什么没有出现"devided by 0!"呢,我们不是要执行三个吗?这是因为程序遇到异常时终止了,停下来让你处理异常,因此程序不会继续向下执行。只有你修正后才可以继续向下执行。
异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。
异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。
try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。
具体知识点见:https://www.runoob.com/cplusplus/cpp-exceptions-handling.html
//异常处理:使用STL的异常类
#include <iostream>
#include <stdexcept>
using namespace std;
class test
{
private:
double m,n;
public:
test(double mm,double nn)
{
m=mm;n=nn;
}
void ave() throw(invalid_argument)//invalid_argument指无效参数。应用在检查参数是否是无效的,是给类的成员变量赋值或者函数参数赋值时,检查其赋给它们的值是否有效,
{
if(n>1)
cout<<m/n<<endl;
else if(n==1)
throw invalid_argument("devided by 1");
else if(n==0)
throw invalid_argument("devided by 0");
}
};
int main()
{
test t1(10,6),t2(10,1),t3(10,0);
try
{
t1.ave();
t2.ave();
t3.ave();
}
catch(exception& e)//exception:该异常是所有标准 C++ 异常的父类。(包含了所有的异常)
{
cout<<"error:"<<e.what()<<endl;//what():用于获取字符串标识异常。此函数返回一个空终止的字符序列,该序列可用于标识异常。
}
return 0;
}
//手工调试:预编译指令
#pragma once//防止重复包含文件
#include <iostream>
using namespace std;
#define _DEBUG//调试开关
class test
{
private:
int n;
public:
test(int nn)
{
n=nn;
#ifdef _DEBUG
cout<<"test::test()"<<endl;
#endif
}
void square()
{
cout<<"square="<<n*n<<endl;
}
~test()
{
#ifdef _DEBUG
cout<<"test::~test()"<<endl;
#endif
}
};
int main()
{
test t(5);
t.square();
#ifdef _DEBUG
cout<<"================="<<endl;
#endif
return 0;
}
注意:#pragma once这个可以写在任何代码的头文件中,作用是防止重复包含文件。例:比如#include "basic.cpp"之类的,那个文件中又包含了重复的头文件。
有关调试开关的知识点:https://blog.csdn.net/u012707739/article/details/80217959
//=======类模板========
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;
template <class T>//模板语句
class test
{
private:
T n;
public:
test(T nn)
{
n=nn;
}
void turn()
{
if(typeid(T)==typeid(int))
{
cout<<"校内车编号-"<<n<<endl;
}
if(typeid(T)==typeid(string))
{
cout<<"校外车牌照-"<<n<<endl;
}
}
};
int main()
{
test <int> t1(123);
t1.turn();
//==============================
test <string> t2("京P00001");
t2.turn();
return 0;
}
//虚函数
#include <iostream>
#include <string>
using namespace std;
class A
{
protected:
int num;
double price;
public:
A(int n,float p)
{
num=n,price=p;
}
virtual void total()
{
cout<<num*price<<endl;
}
};
class B:public A
{
protected:
double tax;
public:
B(int n,double p,double t):A(n,p)
{
tax=t;
}
virtual void total()
{
cout<<num*price*tax<<endl;
}
};
int main()
{
A a(10,5);
B b(10,5,0.15);
A* p;
p=&b;
p->total();
return 0;
}
在这里插入代码片