Boolan c++学习第一周笔记

1.一种基于对象(object based),这种是单一的类的设计;一种面向对象(object oriented),多重class的设计;
对于类中的变量和函数而言,数据有很多份但是函数只有一份。
2.头文件的正规写法:
#ifndef __头文件名__
#define __头文件名__
XXXXXX
#endif
采用了防卫式声明。
3.c++中的模板:
1.如果在类中定义成员数据的数据类型未定义的时候,可以考虑使用模板;
首先在类的声明前先定义一个:
template<typename T>
在类声明中定义数据时候,T  re,im;
再使用的时候,类名<double>c1(2.5,1.5) 告诉编译器定义为double类型。
4.内联函数(inline)
在类本体里面定义的函数就是内联函数;内联函数只是对编译器的建议,不是绝对。
如果不在本体里面定义的函数,想要变为内联函数,使用inline关键字,但是inline关键字对于编译器而言依然只是建议性的,不是绝对要求的。
5.对于数据而言,在类的定义的时候最好写在private里面,作为私有的,成员函数要具体分析具体对待;
为了数据的封装性,在类的定义的时候,我们获取数据一般是通过成员函数,而不是直接获取,直接获取(一般将数据设为private)是不正确的。
6.构造函数:
如果要创建对象,构造函数就会自动被调用起来;构造函数:
函数名和类的名字相同,可以带有参数,同时参数是可以带有默认值的,(这个默认值的作用在于创建对象的时候如果指明了数值则使用致命的,如果没有就是用默认值。)。构造函数是没有返回值,创建好对象之后则构造函数的任务则结束。
complex (double r = 0, double i = 0): re (r), im (i) { }
这种写法更加优秀;
虽然可以写成
{
re = r;
im = i;
}
这种赋值形式和上面的那种形式,效果一样,但是上面的方法更加优秀,
一定的原因为:
一个数据的定义一般分为初始化和赋值两个操作,像上面的操作就是初值列,初始列,而下面的操作就是赋值。效率差一点。
7.函数重载
7.1构造函数很容易出现函数重载,
但是在没有参数以及有默认值的时候,是不可以的。因为如果创造一个对象,不给参数,那么有默认值以及没有参数的这两个构造函数都可以使用,这种情况下会出错,所以是不可以的。
所以有默认值的构造函数不能再去创建无参的同名的构造函数。
7.2
构造函数在private区里面,用在这种情况下就是不允许创建对象,这种情况下就是指允许有自己这一份,不允许再去创建其他的。
8.成员函数:
8.1
只是获取数据的话,就需要加const加修饰,位置卸载函数名的后面,即函数名和参数的小括号的后面。
示例代码:
double real() const{ return re};
real的这个函数没有参数,功能只是将对象的数据进行取出,不进行修改数据,所以加const,将const加在参数的小括号的后面。不改变数据一定要const。
如果在定义对象的时候加了const修饰,那就表明程序员本身是不想改变对象里面的所有的数据的,但是如果定义类的时候在获取数据的成员函数没有加const修饰,那么编译器会告诉程序员是可以改变对象的数据的,这就会造成矛盾,所以假如在定义对象的时候加const修饰,在获取数据的成员函数的也必须要有const修饰。
9.函数的传值(通过值的传递,通过引用传递,pass  by  value,pass by  reference )
9.1整个值传过去,在对应的内存将数据完整的传过去。参数传递最好用引用传递,因为效率比较高,这种情况下适用于大部分情况下。
const complex& 加const修饰,表明程序员不想改变传过来的值,所以定义的类的成员函数不要去修改传递过来的引用。不加const修饰就表明成员函数可以修改传递过的引用。
9.2函数返回至(pass  by  value,pass by  reference)
返回值也尽量使用引用,但是在一些特殊情况下不能使用引用来返回函数的返回值。
返回值类型为XXX&这种就是return by  reference。
10.friend 友元函数。
friend complex& __doapl (complex *, const complex&);
友元函数太多会对封装性造成一定的破坏性
int func(const complex& param)
{
return param.re+param.im;
}
yongfa :
complex c1(2,1);
complex c2;
c2.func(c1);
相同的class的各个对象之间互为友元。
11.class body外的各种定义;
body里面的这些成员函数需要加const一定要去加,可以避免编译器去报错。
函数处理完数据需要将得到的结果存放到一个地方,要么新建一个内存块去存放(这种情况不能使用by  referenc   。因为这是在栈上,函数结束,这块内存就结束了,没用了,所以不能使用引用来返回值),或者就存放在传进来的那块内存里面,
12.操作符重载。
12.1操作符重载--成员函数(this)
+= 这种操作符是二元操作符,示例:ths->re += r.re;  左值和右值两边都存在数值,需要进行操作符运算,在这种二元 操作符的情况之下,编译器看待这个操作符是将它作用于左边的数值,如果左边的对象定义了这个操作符。就去调用那个函数。
譬如:
inline complex&
complex::operator += (const complex& r)
{
return __doapl (this, r);
}
其实,隐藏的东西为:
inline complex&
    complex::operator += (this,const complex& r)
    {
    return __doapl (this, r);
    }
谁作用的就是这个this,二元操作符情况下是右值,this就是这个作用值的指针,.这个this实际上不能写出来的。


inline complex&
__doapl (complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}

inline complex&
complex::operator += (const complex& r)
{
return __doapl (this, r);
}
这个示例代码就是操作符重载的经典示例代码。
讲一个简单的功能写成一个函数,就可以提供给多个函数去调用和使用了。这个this在写代码的时候不能再实参列表中写出来,但是在函数内部使用的时候可以写出来,这个this就是左边对象的指针,可以从这个例子中可以得到验证。
总结:
操作符左右两边,这个操作符作用域左边,然后在看左边对象中是否定义了这个操作符,再去根据this和相关的参数去调用相对应的操作符重载函数。this指向调用者,这种情况我的理解是应该适用于成员函数这种操作符重载的情况。
12.2 返回值通过引用。
inline complex&
__doapl (complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}
这个地方我自己的理解就是this是个指针,然后通过指针取出这个数值,接收者再通过引用的方式去接收,(其实既可以通过引用接收,也可以通过value来接收。这应该就是所谓的传递者无需知道接收者以何种方式接收。)
传递者无需知道接收者是以引用形式接受。

至于在这个例子中。这个+=的返回值定义为complex&,而不是void,其实在单纯的c1+=c2这种情况是可以定义为void,但是在C语言中有所谓的多运算符,c++也兼容,所以在c1 += c2 += c3这种情况下就必须不能将返回值定义为void。所以设计运算符重载的话,要考虑到运算符连起来使用的这种情况下。
12.3
在头文件定义类的时候,在类的body之后定义的函数,如果不带有类名的就是全局函数,带有类名的就是成员函数。
12.4 操作符重载---非成员函数。

inline complex
operator + (const complex& x, const complex& y)
{
return complex (real (x) + real (y), imag (x) + imag (y));
}

inline complex
operator + (const complex& x, double y)
{
return complex (real (x) + y, imag (x));
}

inline complex
operator + (double x, const complex& y)
{
return complex (x + real (y), imag (y));
}
为了考虑多种情况(我个人觉得是实参的不同,即为实参的类型或者是个数不同等这些情况),所以需要考虑些多种情况的重载函数。而且不是成员函数的这种情况,一般是写成全局函数。
这个地方的返回值一定为by  value,不能为by  reference,因为这些得到的结果时临时存放的,所以不能通过引用来传。
而且c++里面,提供了一种临时变量的定义,typename() 这和int  i ,然后使用i是一样的,定义一个临时变量,示例代码:
return complex (x + real (y), imag (y));这就是所谓的临时变量,


inline complex
operator + (const complex& x)
{
return x;
}

inline complex
operator - (const complex& x)
{
return complex (-real (x), -imag (x));
}
在这种情况下,编译器会根据参数的个数来进行函数的选择。第一个也是可以通过引用来传递返回值。

12.5
特殊的操作符只能定义为全局函数。
#include <iostream>
ostream&
operator << (ostream& os, const complex& x)
{
return os << '(' << real (x) << ',' << imag (x) << ')';
}
cout的类型为ostream这种类型。
所以在使用的时候,示例代码为:
cout << c2 << endl;
cout << (c1 += c2);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值