C++ 杂项知识记录
各类C++杂项知识
—————————————————————————————————————————————
1.前置处理符号
1.1 #pragma once
在C和C++编程语言中,#pragma once是一个非标准但是被广泛支持的前置处理符号,会让所在的文件在一个单独的编译中只被包含一次。以此方式,#pragma once提供类似include防范的目的,但是拥有较少的代码且能避免名称的碰撞。
例如
// DefOther.h
#include "demo.h"
void Function();
// demo.h
class demo
{
public:
demo(void);
~demo(void);
bool Initialize(void);
void Update(void);
void Finialize();
private:
int Value;
};
// main.cpp
#include "DefOther.h"
#include "demo.h"
int main() {
return 0;
}
而修改demo.h为下图才可以正常运行
// demo.h
#pragma once // 添加标记
class demo
{
public:
demo(void);
~demo(void);
bool Initialize(void);
void Update(void);
void Finialize();
private:
int Value;
};
2.引用和拷贝构造函数
2.1 引用
1.当引用被创建时,他必须被初始化。(指针可以在任意时候初始化)
2.一旦一个引用被初始化为指向一个对象,它就不能改变为另一个对象的引用(指针则可以在任何时候指向另一个对象)
3.不可能有NULL引用。必须确保引用是和一块合法的存储单元关联。
int a = 1;
int& x = a;
x++;
std::cout<<x<<" "<<a<<std::endl;
// 2 2
引用开发的良好习惯:
普通的函数传值方式需要调用构造函数和析构函数,这时我们可通过常量的引用传递来实现如:void function (Value& v) { … }
2.2 拷贝构造函数
X(&X)
3.运算符重载
3.1 operator-> (灵巧指针)
所谓的灵巧指针即是重载一个对象的->(间接引用运算符),使得一个对象可以像表现的像一个指针,并且这样子一个对象相较于一般的指针有着更多的灵巧性。使用灵巧指针也可以实现类似于迭代器的功能,即可以作用于其他对象与容器上,选择他们的一个进行操作,而不是提供对容器的直接访问。
代码示例:
/* SmartPointer.h */
#include <iostream>
#include <vector>
class Obj{
static int i,j;
public:
void f() const {std::cout<<i++<<std::endl;}
void g() const {std::cout<<j++<<std::endl;}
};
int Obj::i = 47;
int Obj::j = 11;
class ObjContainer {
std::vector<Obj*> a;
public:
void add(Obj* obj){ a.push_back(obj); }
friend class SmartPoomter;
};
class SmartPoomter {
ObjContainer& oc;
int index;
public:
SmartPoomter(ObjContainer& obj) : oc(obj) {
index = 0;
}
bool operator++(){
if(index >= oc.a.size()) return false;
if(oc.a[++index] == 0) return false;
return true;
}
bool operator++(int){
return operator++();
}
Obj* operator->() const{
return oc.a[index];
}
};
/* main.cpp */
#include "SmartPointer.h"
int main() {
std::cout << "Hello, World!" << std::endl;
const int sz = 10;
Obj o[sz];
ObjContainer oc;
for(int i = 0; i < sz;i++)
{
oc.add(&o[i]);
}
SmartPoomter sp(oc);
do{
sp->f();
sp->g();
}while (sp++);
return 0;
}
在类Obj中定义了程序的一些对象,我们通过类ObjContainer的add()方法吧这些对象的指针存储在类ObjContainer这个容器之中,虽然类ObjContainer看起来像个数组,可是它无法直接拿到类Obj。
但是类ObjContainer中声明了类SmartPoomter的友元,使得类SmartPoomter可以直接访问类ObjContainer的方法。
我们先通过operator++使得类SmartPoomter可以在容器移动并不会超出界限,并通过operator->()指向我们所需要的的内容。但很显然,我们现在创建的灵巧指针是与类ObjContainer配套使用的,而不是通用的“迭代器”。