C++程序设计(下)第一周
来源:互联网 发布:神盾阅读器软件 编辑:程序博客网 时间:2024/06/05 02:42
@(boolan C++)[C++]
1.转换函数(conversion fuction)
转换函数一般是类的成员函数。转换函数的作用是,把class转化成某种类型,也可以把其他类型转换为class。
例如,设计一个函数Fraction,在class Fraction里,定义了一个函数,operator double()const {..}这个函数就是转化函数,它的用处是,如果需要把fraction这个类转为double,就调用这个函数;
class Fraction
{
public:
Fraction(int num, int den=1)
: m_numerator(num), m_denominator(den)
{ cout << m_numerator << ' ' << m_denominator << endl; }
operator double() const {
return (double)m_numerator / m_denominator;
}
private:
int m_numerator; //
int m_denominator; //
};
此处便是转化函数起作用的地方。在第一条语句中,构造了一个对象f,下一条语句中,出现了4+f,这时,f并不是double型,Fraction类也没有重载 加号,编译器本应该报错,但是编译器在Fraction类里头找到了operator double()const {..} 有了这个函数,第二条语句就不会报错,因为编译器会调用这个函数,把f转化为double型。
Fraction f(3,5);
double d = 4 + f; //4.6
cout << d << endl;
只要认为合理,类的转换函数可以有多个,转换类型不一定要是基本类型,复合类型也可;
2.non-explict-one-argument ctor
还是用的前面的class Fraction说明。在这里,Fraction的构造函数有两个参数,其中一个有了默认值,默认是1;因此在初始化Fraction对象的时候可以只给一个参数赋值。
class Fraction
{
public:
Fraction(int num, int den=1)
: m_numerator(num), m_denominator(den)
{ cout << m_numerator << ' ' << m_denominator << endl; }
Fraction operator+(const Fraction& f) {
cout << "operator+(): " << f.m_numerator << ' ' << f.m_denominator << endl;
return f;
}
private:
int m_numerator; //
int m_denominator; //
};
在下面的第二条语句中,Fraction重载了加号,但加号左边是一个常量而非Fraction对象,编译器本该报错。但由于Fraction的构造函数可以只有一个参数,所以编译器会自作主张,调用它的构造函数,把4传给第一个参数,这样4+f也是没有错的,下面的语句可以通过。但是如果是第三种情况,即operator double()const {..} 和带默认参数的构造函数同事存在,double b = 4+f就会报错。因为编译器不知道是该将f转化为double型,还是将4转化为Fraction对象。
Fraction f(3,5);
double d = 4 + f; //4.6
cout << d << endl;
但是如果是第三种情况,即operator double()const {..} 和带默认参数的构造函数同事存在,double b = 4+f就会报错。因为编译器不知道是该将f转化为double型,还是将4转化为Fraction对象。所以为了避免出现这种错误,一般会在构造函数前面加一个关键字explict 。它一般用在构造函数或者模板前面,它告诉编译器,构造函数只有在明确表明要调用的时候才可以调用它;这时,编译器就不会把因为遇到4+f这样的情况而去调用它的构造函数了。
3.关于智能指针
template<class T>
class shared_ptr
{
public:
T& operator*() const{return *px;}
T* operator->() const {return px;}
shared_ptr(T* p): px(p) {}
private:
T* px;
long* pn;
}
struct Foo{... void method(void){} };
上面写了一个智能指针类。下面语句的意思是:new一个Foo之后的指针,当成初值,赋值给一个智能指针;
因为智能指针类里面包含指针,所以凡是智能指针,都会重载*和->;
shared_ptr<Foo> sp(new Foo);
4.模板
C++里面的模板可以分为三大类:类模板、函数模板以及成员模板。
类模板,顾名思义,就是在设计类的时候将其中某个成员变量的类型声明为模板;函数模板在使用的时候不必指明和数据类型;而成员模板指的是结构体或者类模板里面包含的模板;
5.三个主题
(1)variadic templates:数量不定的模板参数
在C++11标准中,新增加了一种语法 ... 这个语法的意思是我不确定我又多少个,所以用...表示省略。
在下面的语句中,我们可以看到template的第一个参数是typename T,第二个参数是typename... Type,这表明设计者在设计初期也不确定其参数个数,只有到了使用的时候才知道。在print函数里, 函数体的第一条语句是输出第一个参数,然后第二条语句,print函数调用自己,参数便是第一次调用print剩下的那些参数,即:const Type&...args ,这些值依次传给print函数,它依次将它们输出。
template<typename T,typename.. Types>
void print(const T&firstArg,const Types&...args)
{
cout<<firstArg<<endl;
print(args...);
}
测试:
print(7.5,"hello",bitset<16>(377),42);
结果:
7.5
hello
0000000101111001
42
(2)auto关键字
一般来说,如果我们声明一个容器,并且需要用到迭代器,那么,应该像下面这样写:
list<string> C;
list<string>::iterator it;
it = find(c.begin(),c.end(),target);
但是如果觉得写那么多太麻烦,还可以用auto关键字简化,写成下面这样。auto关键字用处是,设计者可以不明确写出变量的类型,编译器会根据上下语句自行判断。
就像下面的语句,find会返回一个迭代器,所以编译器知道it的类型是迭代器,因此我们不必像上面那样将it声明为迭代器。
但是要注意的是,尽管用auto很省事,但是不能全部用它,否则很容易出现混乱。
list<string> c;
...
auto it = find(c.begin(),c.end(),target);
还有一种情况,下面的写法是不正确的。auto只能用在编译器可以明确判断出变量的类型的地方,而不能用来声明变量。用auto声明变量,编译器也不会知道这个变量是什么类型的。
list<string> c;
auto it;
it = find(c.begin(),c.end(),target);(不正确)
(3)ranged-banse for(C++11)
这也是C++11的新语法
for(decl : coll)
{statement}
for(int i : {2,3,4,5,6,7,8})
{cout << i << endl;}
6.引用 --用法小结
(1)引用一定要赋初值;
(2)引用一旦绑定对象后将不能再绑定到其他对象;
(3)引用是对象的一个代表 ,所以引用的地址、大小都和对象相同,但都是假象;
(4)我们很少用引用声明变量,一般用于参数类型和返回类型;
(5)下面被视为有“相同签名”(所以二者不能同时存在),这是因为这两个函数在调用的时候语法是一样的,都是 image(im);
double image(const double& im){...}
double image(const double im){...}
如果同时声明了这两个函数,那么在调用次函数的时候,会产生二义性;
不过如果加了const就不会了,const也是函数签名的一部分,函数签名有没有const是不一样的。
- C++程序设计(下)第一周
- 程序设计与算法(一)C语言程序设计CAP 第一周
- c语言程序设计(第一周)
- Coursera 程序设计实习 / Practice on Programming 笔记(第一周)
- 第一周《C语言及程序设计》资料1--C语言助记图
- 第一周 《C语言及程序设计》资料2——C语言中数学函数
- 极客班C++(下)第一周笔记——operator+的几种实现
- 极客班 c++(下)第一周学习笔记 ——new & delete
- 第一周《C语言及程序设计》实践项目7 分支结构程序体验
- 第一周《C语言及程序设计》实践项目11 算术运算符与算术表达式
- 第一周《C语言及程序设计》实践项目19 字符数据及字符类型
- 第一周《C语言及程序设计》实践项目23 用if语句实现分支结构
- 第一周《C语言及程序设计》视频笔记数据的输入
- 第一周《C语言及程序设计》视频笔记数据的输出
- 第一周《C语言及程序设计》实践项目24 if语句的嵌套
- 网易云课堂程序设计入门--C语言第一周 简单的计算程序学习笔记
- 网易云课堂-程序设计入门-C语言-第一周:简单的计算程序
- C++程序设计基础一周目第七天
- 创建字体信息设置界面
- 实战Linux Bluetooth编程(二) BlueZ简介
- 杭电ACM OJ 1012 u Calculate e 乍一看很简单的公式题 其实需要从题中分析出两个递归来 非常巧妙!
- 第十一周【项目2
- js向java后台传汉字乱码的解决方法
- C++程序设计(下)第一周
- vue组件(二)
- windows 7下硬盘安装Ubuntu遇到的问题
- React Native 网络请求
- Mosaic HDU
- mysql 查询中文乱码
- 史上最全面的CentOS 7 之 redis 安装
- 复杂选择器 内容生成 多列 CSSHack(浏览器兼容)
- Android_XRecyclerView上拉下拉加载数据