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

一、 #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 PERSONAL
class 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.











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值