内联函数
内联函数头文件.h
//内联函数头文件.h
#ifndef DEMO_H
#define DEMO_H
#include<string>
//带有inline的函数叫内联函数(执行速度快)(短小的函数)
inline int sum(int a, int b)
{
return a + b;
}
inline const std::string& shortString(const std::string& s1, const std::string& s2)
{
return s1.size() < s2.size() ? s1 : s2;
}
inline bool isShorter(const std::string& s1, const std::string& s2)
{
return s1.size() < s2.size();
}
#endif
内联函数.cpp
//内联函数.cpp
#include<iostream>
#include"内联函数头文件.h"
using namespace std;
int main()
{
int x[] = { 1,2,3,4,5,6,7,8,9 };
int y[] = { 1,2,3,4,5,6,7,8,9 };
for (int i = 0;i < 9;++i)
cout << sum(x[i] , y[i]) << endl;
cout << shortString("hello", "bill") << endl;
cout << isShorter("Guoyan", "Zeng") << endl;
return 0;
}
函数重载
#include<iostream>
#include<vector>
//重载函数 函数类型和名称一样 形参不同
//不同类型 名称和形参一样不叫函数重载
using namespace std;
class Account
{
};
class Phone
{
};
class Name
{
};
class Record
{
public:
Account a;
Phone b;
Name c;
};
void lookup(const Account& acct)
{
cout << "使用账号进行查找" << endl;
}
void lookup(const Phone& phone)
{
cout << "使用电话进行查找" << endl;
}
void lookup(const Name& name)
{
cout << "使用姓名查找" << endl;
}
void show(int x)
{
cout << x << endl;
}
void show(vector<int>v)
{
for (vector<int>::iterator iter = v.begin();iter != v.end();++iter)
cout << *iter << endl;
}
//不重载函数
class MyScreen
{
public:
void moveHome();
void moveAbs(int,int);
void moveRel(int, int, char* direction);
};
class YourScreen
{
public:
void move();
void move(int, int);
void move(int, int, char* direction);
};
int main()
{
/* MyScreen m;
YourScreen n;
m.moveHome();
n.move();*/
Account x;
Phone y;
Name z;
lookup(x);
lookup(y);
lookup(z);
int a = 89;
vector<int> b;
b.push_back(1);
b.push_back(2);
b.push_back(3);
show(a);
show(b);
return 0;
}
类外的函数 和类内的函数
#include<iostream>
#include<string>
using namespace std;
int sum(int x, int y)
{
return x + y;
}
// 销售 项目
class Sales_item//class 要变成对象才能使用!
{
public:
double avg_price() const;//函数原型声明
bool same_isbn(const Sales_item& rhs) const;//函数原型声明
//{
// // 当前对象
// return this->isbn == rhs.isbn;
//}
public:
Sales_item():units_sold(0),revenue(0){}//类构造函数
//private:
public:
std::string isbn;//书号
unsigned units_sold;//数量
double revenue;//金额
};
double Sales_item::avg_price() const// Sales_item::这是放在类外需要的
{
if (this->units_sold)
return(this->revenue / this->units_sold);
else
return 0;
}
bool Sales_item::same_isbn(const Sales_item& rhs) const
{
// 当前对象
return this->isbn == rhs.isbn;
}
int main()
{
Sales_item item1, item2;//类class
item1.isbn = "0-201-4536-X";
item1.units_sold = 10;
item1.revenue = 300.00;
cout << item1.avg_price() << endl;
item2.isbn = "0-201-4536-X";
item2.units_sold = 2;
item2.revenue = 70.00;
cout << item2.avg_price() << endl;
if (item1.same_isbn(item2))//same_isbn是成员函数 必须通过对象item1来调用这个函数
cout << "这两个sales item是同一种书!" << endl;
else
cout << "这两个sales item不是同一种书!" << endl;
return 0;
}
类的构造函数
#include<iostream>
using namespace std;
class Person
{
public:
//默认的构造函数 ()无参数
Person() :钱(9999)
{
//可以空着
}
public:
int 钱;
};
int main()
{// a和我 都是对象,原来没有这两个对象
Person a;//创建对象a时,通过调用Person的构造函数创建对象
Person 我;//这一行就是创建对象
cout << a.钱 << endl;
cout << 我.钱 << endl;
return 0;
}
类的头文件和源文件
类的头文件
#ifndef _类的成员函数
#define _类的成员函数
#include<string>
// 销售 项目
class Sales_item//class 要变成对象才能使用!
{
public:
double avg_price() const;//函数原型声明
bool same_isbn(const Sales_item& rhs) const;//函数原型声明
//{
// // 当前对象
// return this->isbn == rhs.isbn;
//}
//private:
public:
std::string isbn;//书号
unsigned units_sold;//数量
double revenue;//金额
};
#endif
类的源文件
#include<iostream>
#include"类的成员函数.h"
#include<string>
using namespace std;
int sum(int x, int y)
{
return x + y;
}
double Sales_item::avg_price() const// Sales_item::这是放在类外需要的
{
if (this->units_sold)
return(this->revenue / this->units_sold);
else
return 0;
}
bool Sales_item::same_isbn(const Sales_item& rhs) const
{
// 当前对象
return this->isbn == rhs.isbn;
}
int main()
{
Sales_item item1, item2;//类class
item1.isbn = "0-201-4536-X";
item1.units_sold = 10;
item1.revenue = 300.00;
cout << item1.avg_price() << endl;
item2.isbn = "0-201-4536-X";
item2.units_sold = 2;
item2.revenue = 70.00;
cout << item2.avg_price() << endl;
if (item1.same_isbn(item2))//same_isbn是成员函数 必须通过对象item1来调用这个函数
cout << "这两个sales item是同一种书!" << endl;
else
cout << "这两个sales item不是同一种书!" << endl;
return 0;
}
类的构造函数
#include<iostream>
#include<string>
using namespace std;
class Dog
{
public:
int 数量;
string 名称;
};
Dog a;//全局对象
int main()
{
cout << "Hello,构造函数!" << endl;
Dog a;//创建对象a 局部对象
//static Dog a;//静态对象 相当于全局对象
cout << a.名称 << endl;
cout << a.数量 << endl;
return 0;
}
类函数和作用域
最好不用局部的函数声明
#include<iostream>
using namespace std;
//全局函数声明
void print(const string&);
void print(double);
void print(int);
void foorBar(int ival)
{
//void print(int);局部函数声明 发生函数隐藏 最好不用
print("Hello");//被隐藏
print(ival);
print(3.14);//被隐藏
}
int main()
{
foorBar(6);
return 0;
}
void print(const string&s)
{
cout << "string:" << s << endl;
}
void print(double d)
{
cout << "double:" << d << endl;
}
void print(int i)
{
cout << "int:" << i << endl;
}
函数重载 和作用域2
#include<iostream>
#include<string>//字符串
using namespace std;
string init()
{
return "Hello";
}
void fcn()
{
string s = init();
cout << s << endl;
}
int main()
{
fcn();
return 0;
}
- “const char *” 类型的实参与 “char *” 类型的形参不兼容之类的错误
C++项目中经常会定义如下形式的字符串char *testString = “This is test string…”;
这样一直用的没有问题, 但今天突然编译报错了~!报错:“const char *” 类型的实参与 "char " 类型的形参不兼容之类的错误, 函数形参为char的类型直接写入字符串也会报错, 这可就郁闷了, 上网查找竟然没有找到解决方法, 但是在另一个电脑同一个项目就不会报错, 都是VS2017, 一个WIN10家庭版一个WIN10专业版, 这种错误竟然丝毫没有头绪, 中间过程也不废话了, 最后的解决办法其实很简单, 在项目属性->C/C+±>语言中的符合模式项选择否即可!!就是这么任性, 记录一下以防以后忘掉了XXXX…
重载示例–多个同名的函数 对名称进行重载
//leftover.cpp--overloading the left() function
#include<iostream>
unsigned long left(unsigned long num, unsigned ct);
char* left(const char* str, int n = 1);
int main()
{
using namespace std;
char* trip= "Hawaii!!";//test value这个初始化报错
unsigned long n = 12345678;//test value
int i;
char* temp;
for (i = 1;i < 10;i++)
{
cout << left(n, i) << endl;
temp = left(trip, i);
cout << temp << endl;//point to temporary storage
}
//cin.get();
return 0;
}
//This function returns the first ct digits of the number num.
unsigned long left(unsigned long num, unsigned ct)
{
unsigned digits = 1;
unsigned long n = num;
if (ct == 0 || num == 0)
return 0;//return 0 if no digits
while (n /= 10)
digits++;
if (digits > ct)
{
ct = digits - ct;
while (ct--)
num /= 10;
return num; //return left ct digits
}
else //if ct>=number of digits
return num; //return the whole number
}
//This function returns a pointer to a new string
//consisting of the first n characters in the str string
char* left( const char* str, int n)
{
if (n < 0)
n = 0;
char* p = new char[n + 1];//new string
int i;
for (i = 0;i < n && str[i];i++)
p[i] = str[i];//copy characters
while (i <= n)
p[i++] = '\0';//set rest of string to '\0'
return p;
}
对象、继承和引用
//filefunc.cpp-- function with ostream & parameter
#include<iostream>
#include<fstream>//派生类 继承基类的方法
#include<cstdlib>
using namespace std;
void file_it(ostream& os, double fo, const double fe[], int n);
const int LIMIT = 5;
int main()
{
ofstream fout;
const char* fn = "ep-data.txt";
fout.open(fn);
if (!fout.is_open())
{
cout << "Can't open " << fn << ".ByE.\N";
exit(EXIT_FAILURE);
}
double objective;
cout << "Enter the focal length of your"
"telescope objective in mm:";
cin >> objective;
double eps[LIMIT];
cout << "Enter the focal lengths,in mm,of" << LIMIT
<< "eyepieces:\n";
for (int i = 0;i < LIMIT;i++)
{
cout << "Eyepiece #" << i + 1 << ":";
cin >> eps[i];
}
file_it(fout, objective, eps, LIMIT);
file_it(cout, objective, eps, LIMIT);
cout << "Done\n";
//cin.get();
//cin.get();
return 0;
}
void file_it(ostream& os, double fo, const double fe[], int n)
{
//save initial formatting state
ios_base::fmtflags initial;
initial = os.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize sz = os.precision(0);
os << "Focal length of objective:" << fo << "mm\n";
os.precision(1);
os.width(12);
os << "f.1.eyepiece";
for (int i = 0;i < n;i++)
{
os.widen(12);
os << fe[i];
os.width(15);
os << int(fo / fe[i] + 0.5) << endl;
}
//restore initial formatting state
os.setf(initial, ios_base::floatfield);
os.precision(sz);
}
将引用用于类对象
//strquote.cpp --different designs
#include<iostream>
#include<string>
using namespace std;
string version1(const string& s1, const string& s2);
const string& version2(string& s1, const string& s2);//has side effect
const string& version3(string& s1, const string& s2);//bad design
int main()
{
string input;
string copy;
string result;
cout << "Enter a string:";
getline(cin, input);
copy = input;
cout << "Your string enhanced:" << input << endl;
result = version1(input, "***");
cout << "Your string enhanced:" << result << endl;
cout << "Your original string:" << input << endl;
result = version2(input, "###");
cout << "Your string enhanced:" << result << endl;
cout << "Your original string:" << input << endl;
//cin.get();
//cin.get();
return 0;
}
string version1(const string& s1, const string& s2)
{
string temp;
temp = s2 + s1 + s2;
return temp;
}
const string& version2(string& s1, const string& s2)//has side effect
{
s1 = s2 + s1 + s2;
//safe to return reference passed to function
return s1;
}
const string& version3(string& s1, const string& s2)
{
string temp;
temp = s2 + s1 + s2;
//unsafe to return reference to local variable
return temp;
}
函数重载 函数匹配
#include<iostream>
using namespace std;
void d() { cout << "d()" << endl; }
void f() { cout << "f()" << endl; }
void f(int a) { cout << "f(int a)" << endl; }
void f(int a, int b) {cout<<"f(int a,int b)" << endl;}
void f(double a, double b=3.14) { cout << "f(double a,double b=3.14)" << endl; }
void g(int a) { cout << "g(int a)" << endl; }
int main()
{
f(8);//f(int a) 最佳匹配
f(5.6);//可行函数 f(int a ,int b)和f(double a,double b=3.14)
//无最佳匹配
//f(42, 2.56);有二义性
//f(2.56, 42); 有二义性
f(static_cast < double>(42), 2.56);//强制转型
f(42, static_cast<int>(2.56));
f(1.2, 8.9);
f(12, 89);
return 0;
}
实参类型转换
#include<iostream>
using namespace std;
class Account
{
public:
Account(){}
Account(int x) :num(x) {}
public:
int num;
};
//枚举类型
enum Tokens
{
INLINE=128,
VIRTUAL=129
};
//重载函数
void lookup(Account& x) { cout << "lookup(Account & x)" << endl; }
void lookup(const Account& y) { cout << "lookup(const Account &y)" << endl; }
//指针
void f(int* p) { cout << "f(int *p)" << endl; }
void f(const int* p) { cout << "f(const int *p)" << endl; }
void newf(unsigned char x) { cout << "newf(unsigned char x)" << endl; }
void newf(int y) { cout << "newf(int y)" << endl; }
void ff(Tokens t) { cout << "ff(Tokens t)" << endl; }
void ff(int x) { cout << "ff(int x)" << endl; }
void ff(short y) { cout << "ff(short)" << endl; }
//void mainp(long x) { cout << "mainp(long x)" << endl; }
void mainp(float y) { cout << "mainp(float y)" << endl; }
void mainp(double x) { cout << "mainp(double x)" << endl; }
int main()
{
int m = 5, n = 6;
int* p = &m;
const int* p2 = &n;//不用*p 用*p2 换一个变量
f(p);//不是f(int*p)
f(p2);
const Account a(0);
Account b;
lookup(a);
lookup(b);
Tokens curTok = INLINE;//枚举变量
unsigned char uc = 129;//枚举调用 unsigned char表示没有符号的字符
newf(VIRTUAL);
newf(uc);//129 就是int 了
ff(curTok);
ff(INLINE);
ff(128);
ff('a');//int 比short 优先
mainp(3.14);
return 0;
}
指向函数的指针
#include<iostream>
#include<string>
#include<vector>
using namespace std;
typedef bool(*cnFne)(const string& , const string& );
typedef int(*PF)(int *p,int a);//37行
bool lengthCompare(const string&s1, const string&s2)
{
return s1.size() == s2.size();
}
string::size_type sumLength(const string & s1, const string & s2)
{
return s1.size() + s2.size();
}
bool cstringCompare(char* s1, char* s2)
{
return strlen(s1) == strlen(s2);
}
void useBigger(const string& s1,
const string& s2,
bool (*pf)(const string& s1, const string& s2)
)
{
cout << pf(s1, s2) << endl;
}
int demo(int* p, int a)
{
return 12;
}
// ff是一个函数,有一个形参x,返回结果是一个函数的指针int(*)(int *,int)
//int (*ff(int x))(int*, int)
PF ff(int x )
{
cout << x << endl;
return demo;
}
void ff(vector<double>vec)
{
cout << "ff(vector<double>vec)" << endl;
}
void ff(unsigned int x)
{
cout << "ff(vector<double>vec)" << endl;
}
int main()
{
//void(*pf5)(int) = &ff;int 和unsigned int不符合
//double(*pf6)(vector<double>) = &ff; 返回的double 和void 不符合
void (*pf8)(unsigned int) = &ff;
void (*pf7)(vector<double>) = &ff;
//普通变量
int a = 5;
int* pa = &a;
cnFne pf4 = lengthCompare;//函数名称就是一个指针
useBigger("hi", "functions", pf4);
cout<<ff(3)(&a,a)<<endl;//调用了ff() 又调用了demo函数
// () pf是一个指针, 指向函数的指针: 函数类型
// pf 是一个局部变量
bool (*pf)(const string&, const string&);
cnFne pf2=0;//初始化
cnFne pf3=0;//初始化 没有指向任何一个函数
pf = &lengthCompare;//函数指针 &可要可不要
pf2 = lengthCompare;
pf3 = lengthCompare;
cout << lengthCompare("Hello", "point") << endl;
cout << (*pf)("Hello", "point") << endl;
cout << pf("Hello", "point") << endl;
cout << pf2("Hello", "point") << endl;
cout << pf3("Hello", "point") << endl;
cout << *pa << endl;
return 0;
}
标准IO库:面向对象的标准库
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
using namespace std;
//void print(ofstream &of)
//{
// cout << "test!" << endl;
//}
ofstream& print(ofstream& of)
{
cout << "test!" << endl;
ofstream of2;
return of2;
}
void foo(ostream& og)//基类
{
cout << "test ostream" << endl;
}
int main()
{
foo(cout);//cout属于ostream
ofstream ofs;//ofstream是ostream的派生类 继承
foo(ofs);
ostringstream oss;
foo(oss);
//cout 是ostream输出流对象
cout << "Hello,c++!" << endl;
std::fstream f;
std::streampos;
ofstream out1, out2;
print(out1);
return 0;
}
流的条件状态
#include<iostream>
using namespace std;
void check_cin_state(istream& is)
{
if (is.bad())
cout << "cin bad" << endl;
else
cout << "cin not bad" << endl;
if (is.fail())
cout << "cin fail" << endl;
else
cout << "cin not fail" << endl;
//end of file
if (is.eof())
cout << "cin eof" << endl;
else
cout << "cin not eof()" << endl;
if (is.good())
cout << "cin good()" << endl;
else
cout << "cin not good()" << endl;
}
int main()
{
cout << "检查cin的状态:" << endl;
// 00011100二进制
//cin.setstate(istream::badbit);强制的改状态
//cin.setstate(istream::failbit);
cin.setstate(istream::badbit | istream::failbit);//同时强制改变两个状态
cin.clear(istream::badbit);//清除badbit状态
cin.clear();//(istream::badbit | istream::failbit);//同时清除两个状态
istream::iostate old_state = cin.rdstate();//保存流的状态
//使用流
cin.clear(old_state);//使用后还原 流的状态
check_cin_state(cin);
cout << "请输入一个整数" << endl;
int n;
cin >> n;
cout << "再检查一次cin的状态" << endl;
return 0;
}
流的状态2
#include<iostream>
using namespace std;
int main()
{
int sum = 0, value;
//这是一个简单的方法
/*while (cin >> value)
{
sum += value;
cout << "Sum is " << sum << endl;
}*/
//更好的方法
while (cin >> value, !cin.eof())
{
if (cin.bad())
throw std::runtime_error("IO stream corrupted");
if (cin.fail())
{
cerr << "bad data,try again" << endl;
cin.clear();//恢复流的状态
cin.ignore(200, '\n');
continue;
}
sum += value;
cout << "Sum is " << sum << endl;
}
return 0;
}
文件流对象的使用
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream outfile("test.txt");//创建txt文件
outfile << "hello file!";//在txt文件里写内容
outfile.close();
string file("ep-data.txt");
//ifstream infile(file.c_str());//打开ep-data文件 必须写c_str()
ifstream infile;//流对象infile 没有和一个文件夹绑定
infile.open(file.c_str());//绑定
//if(infile)打开文件成功
if (!infile)
{
cerr << "error:unable to open input file:"
<< file << endl;
return -1;
}
string s;//读文件
// infile状态是eof
while(infile >> s)
cout << "读到的内容是" << s << endl;
infile.close();
infile.clear();//恢复流的状态
file = "test.txt";
infile.open(file.c_str());
if (!infile)
{
cerr << "error:unable to open input file:"
<< file << endl;
return -1;
}
return 0;
}
文件模式
-文件模式选项: in. out. app. ate. trunc. binary (二进制模式)
- 文件模式组合:
out
out | app
out | trunc
in
in | out
in | out | ate
in | out | trunc
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
string s;
//ifstream ifs("test.txt", ifstream::in);
ifstream ifs("test.txt");
if (!ifs)
{
cerr << "error:unable to open file!" << endl;
return -1;
}
ifs >> s;//读文件 输入
ifs.close();
cout << s << endl;
//ofstream ofs("test1.txt", ofstream::out);//本来没有test1文件 创建了test1文件
ofstream ofs("test2.txt");//文件输出流ofstream 创建了文件test2
ofs << "Hello test.txt" << endl;
ofs.close();
//ofstream ofs1("test.txt");//不能写ofs 这样重定义了
// ofstream ofs1("test.txt", ofstream::out);
// ofstream ofs1("test.txt", ofstream::out | ofstream::trunc);//trunc 为截断
//上面三行是一样的 直接改test文件的内容
ofstream ofs1("test.txt", ofstream::out | ofstream::app);//这个是在test文件中 追加内容
ofs1 << "C++!" << endl;//这里以及后面close 都要写成ofs1 不然test为空文件
ofs1.close();
//fstream fs("test.txt");
//fstream fs("test.txt", fstream::in | fstream::out);//不会清空
//上面两行一样
fstream fs("test.txt", fstream::in | fstream::out | fstream::trunc);//要清空
ifs >> s;
ifs.close();
cout << s;
//fstream fs2("test.txt");//鼠标定位到文件开头
fstream fs2("test.txt", fstream::in | fstream::out|fstream::ate);//鼠标定位到文件最后
//fstream fs2("test.txt",fstream::ate);不行
fs2 << "rest";
fs2.close();
return 0;
}
字符串流
- 字符串流:内存中的输入和输出
istringstream. ostringstream . stringstream
-字符串流stringstream特定的操作
stringstream strm;
stringstream strm(s);
strm.str()
strm.str(s)
- stringstream提供的转换和格式化
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
int main()
{
//cout是流对象 ,ostream
cout << "Hello!" << endl;
//ofs是文件输出流对象
ofstream ofs("test.txt");
ofs << "hello!" << endl;
ofs.close();
//字符串输出流
ostringstream oss;
oss << "Hello!" << endl;
cout <<"显示字符串流里面的字符串"<< oss.str() << endl;
ostringstream format_message;
format_message << "姓名:" << "张飞" << "\n"
<< "年龄:" << 22 <<"\n"
<< "体重:" << 88.5 << "\n";
cout << "显示张飞:\n" << format_message.str() << endl;
string dump;
string 姓名;
int 年龄;
double 体重;
istringstream input_istring(format_message.str());
input_istring >> dump;
input_istring >> 姓名;
input_istring >> dump;
input_istring >> 年龄;
input_istring >> dump;
input_istring >> 体重;
return 0;
}
#include<iostream>
#include<fstream>//文件流
#include<sstream>//字符串流
#include<vector>
using namespace std;
int main()
{
string fileName, s;
vector<string>svec;
istringstream isstream;
string word;
fileName = "ep-data.txt";
ifstream inFile(fileName.c_str());
if (!inFile) return -1;
while (getline(inFile, s))
svec.push_back(s);
inFile.close();
for (vector<string>::const_iterator iter = svec.begin();
iter != svec.end();++iter)//(;;)
{
// cout << *iter << endl;
isstream.str(*iter);
while (isstream >> word)
{
cout << word << endl;
}
isstream.clear();
}
return 0;
}