【C++数据结构与算法】学习随笔一

来源:互联网 发布:汽车轮毂数据大全 编辑:程序博客网 时间:2024/05/16 13:37

一、 #ifndef/#define/#endif的使用

#ifndef/#define/#endif 防止该头文件被重复引用,“被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。比如:存在a.h文件#include "c.h"而此时b.cpp文件引用了#include "a.h" 和#include "c.h"此时就会造成c.h重复引用。

造成重复引用的后果,只是增加了编译工作的工作量,不会引起太大的问题,仅仅是编译效率低一些,但是对于大工程而言编译效率低下将是严重的问题。为了良好的编程习惯

建议每个类都加入#ifndef/#define/#endif标志。

例子:

#ifndef PERSONAL#define PERSONALclass Personal{}#endif

二、类模板 template <class T>

比如定义了某些类,需要对这些类进行相应的数据操作,使用类模版来定义操作类,赋予不同的数据类型即可进行操作。

template<class T>//声明类模版,class定义虚拟类型,T为虚拟类型名(在使用时需要具体指定类型,至于虚拟类型名是什么自己指定)class Database {public:    Database();    void run();private:    fstream database;    char fName[20];    ostream& print(ostream&);    void add(T&);//使用虚拟类型名T进行add操作,在该成员函数定义的时候也需要使用类模版的形式,如下代码    bool find(const T&);    void modify(const T&);    friend ostream& operator<<(ostream& out, Database& db) {        return db.print(out);    }};

template<class T>//声明模版类void Database<T>::add(T& d) {//数据类型为虚拟类型T(红色标出为主要两点,所属类和函数形参都需要用虚拟类型T)    database.open(fName,ios::in|ios::out|ios::binary);    database.clear();    database.seekp(0,ios::end);    d.writeToFile(database);    database.close();}

在声明好类模版之后,需要调用类模版,调用如下:

Database<int> data_int;//需要为虚拟类型赋予实际的类型名(虚拟类型实例化,给予实际类型)int a=2;data_int.add(a);

三、friend ostream &operator<<(ostream &stream, const Date& dt);

c++中有个friend关键字,它能让被修饰的对象冲破本class的封装特性,从而能够访问本class的私有对象。
简单来讲,就是:
如果你在A类中,申明了函数func()是你的friend,那么func()就可以使用A类的所有成员变量,无论它在什么地方定义的。
如果你在A类中,申明了B类是你的friend,那么B类中的方法就可以访问A类的所有成员变量。

class A {public:    A() {        password = 1111;        birthday = 808;    }    ~A() { }    friend int func(A a); // 向c++表示,int func(A a)是我的朋友,所以它可以使用我的所有东西。    friend class B;       // 向c++表示,class B是我的朋友,所以它可以使用我的所有东西。private:    int password;    int birthday;};

运用friend重载 << 或者 >>操作

friend ostream &operator<<(ostream &stream, const Date& dt);//利用friend特性对<<操作符进行了重载,函数返回值为ostream&类型,赋予了新的功能。operator是操作符的意思,后面紧跟相应的操作符(相当于“operator 对应操作符”就相当于一个函数名) 

 friend ostream& operator<<(ostream& out, Database& db) {        return db.print(out);//重载<<操作符,函数<<操作符可以访问类中的所有成员变量(无论定义在哪)调用db对象中的print函数执行输出;    }

四、getline的使用

getline(istream &in, string &s)
从输入流读入一行到string s
•功能:
–从输入流中读入字符,存到string变量
–直到出现以下情况为止:
•读入了文件结束标志
•读到一个新行
•达到字符串的最大长度
读到一行赋给s返回true,如果getline没有读入字符,将返回false,可用于判断文件是否结束

五、标准转换运算符reinterpret_cast

reinterpret_cast <new_type> (expression) // reinterpret_cast <另一种类型> (原类型,原类型大小(sizeof(类型名)))
reinterpret_cast是强制类型转换符!他是用来处理无关类型转换的,通常为操作数的位模式提供较低层次的重新解释!但是他仅仅是重新解释了给出的对象的比特模型,并没有进行二进制的转换!他是用在任意的指针之间的转换,引用之间的转换指针和足够大的int型之间的转换,整数到指针的转换,通常可将*int强制转为*char用于对整数的存储和表示。

int *pi; char *pc = reinterpret_cast<char*>(pi,sizeof(int)); 
但是要注意的是,他并没有进行二进制的转换,pc指向的真实对象其实还是int,不是char.