C++重难点知识

1.顶层const和底层const

 const int a=10;

 int b=5;

 const int *p1=&a;

 int (*const)p2=&b;

  

p1是顶层const,表示p1是一个指向常量的指针,不能用修改(*p1)的值,p2是底层const,表示p2是一个常量指针,即不能改变p2的值。

2.类成员函数参数列表后面为什么要加const?

例如定义一个表示平面点的类。

struct zz

{

  int x,y;

     bool operator <(const zz&u)const

  {

    return x<u.x;
  }

}

  

调用重载的<时,实际上是隐式的使用了this指针,this指向<前面的对象,且是常量指针,这样this就无法绑定到一个常量上,为了增加程序的灵活性,将this变为一个指向常量的常量指针,这样无论<前面是不是常量都能顺利的绑定上去。如果加了const则不能改变<前面的对象的值。

3.指向函数的指针

首先要弄清楚函数的类型,函数类型由函数的返回类型和函数的参数列表确定,并且是精确匹配。

比如int Add(int a,int b)它的类型就是int (int ,int),而int *(int ,int )就表示指向函数的指针。

定义:

  int Add(int a,int b);
int (*p)(int ,int);   decltype(Add)p1; p=Add;      

  p表示的就是指向函数Add的指针,相当于是函数的另一个名字,可以像调用add一样调用p。p1和p的定义等价。

下面是一个用vector储存并调用函数指针的例子:

#include<iostream>
#include<cassert>
#include<string>
#include<vector>
using namespace std;
int main()
{
	int f(int,int);
	int jia(int ,int);
	int jian(int ,int);
	int cheng(int ,int);
	int chu(int,int);
	vector<decltype(f)*>s1;
	vector<int(*)(int ,int)>s2;
	s2.push_back(jia);
	s2.push_back(jian);
	s2.push_back(cheng);
	s2.push_back(chu);
	int a,b;
	cin>>a>>b;
	for(auto c:s2)
		cout<<c(a,b)<<endl;
}
int jia(int a,int b)
{
	return a+b;
}
int jian(int a,int b)
{
	return a-b;
}
int cheng(int a,int b)
{
	return a*b;
}
int chu(int a,int b)
{
	return a/b;
}

4.函数类型后置

对于一些类型比较复杂的函数,可以使用函数类型后置。

     int a[5]={1,2,3,4,5};
     auto func(const int &i) -> int (&)[5];

 这里,func返回的是数组的引用,即它返回的值等价于数组。

#include<iostream>
using namespace std;
int main()
{
	int Add(int ,int);
	auto p(int) ->int(*)(int ,int);
}

 这里,p返回的是一个指向函数的指针。

5.数组作为形参

有两种方法实现

(1):传入指针

#include<iostream>
using namespace std;
int a[5],b[5];
int main()
{
	int print(int [],int);
	print(a,5);
}
void print(int p[],int len)
{
	for(int i=0;i<len;i++)
		cout<<*(p+i)<<' ';
}

 这里把数组的首地址传进了函数中,int []可以替换成int *,同时需要传入数组的大小,防止越界。

(2):传入数组的引用

#include<iostream>
using namespace std;
int a[5],b[5];
int main()
{
	int print(int (&)[5]);
	print(a);
}
void print(int (&p)[5])
{
	for(auto c:p)
		cout<<c<<' ';
}

 这里把数组的引用作为参数传递了进去,此时的p就相当于a,注意数组类型里包含了数组的大小,用这种方法必须表明数组的大小。

 6.定义接口函数读入(输出)自定义类类型

#include<bits/stdc++.h>
using namespace std;
struct Sales_data
{
	string isbn()const{return bookNo;}
	Sales_data& combine(const Sales_data &other)
	{
		revenue+=other.revenue;
		units_sold+=other.units_sold;
		return *this;
	}
	string bookNo;
	double revenue=0.0;
	int units_sold=0;
	double price=0.0;
};
istream &read(istream &is,Sales_data& item)
{
	is>>item.bookNo>>item.units_sold>>item.price;
	item.revenue=item.price*item.units_sold;
	return is;
}
ostream &print(ostream &os,const Sales_data &item)
{
	os<<item.bookNo<<' '<<item.units_sold<<' '<<item.revenue;
	return os;
}
Sales_data add(const Sales_data&a1,const Sales_data&a2)
{
	Sales_data sum=a1;
	sum.combine(a2);
	return sum;
}
int main()
{
	Sales_data b1,b2;
	read(cin,b1);
	read(cin,b2);
	print(cout,add(b1,b2));
}

 istream和ostream属于IO类型,且IO类型不能拷贝,所以只能定义成引用类型。

read函数里面Sales_data不能定义成常量引用,因为要对它进行修改,return is是因为要检查是否读到了文件尾。

print函数因为不用修改Sales_data,所以可以定义成常量引用。

posted @ 2015-12-13 16:44  UESTC-Ulysses  阅读(456)  评论(0编辑  收藏  举报