1.友元
- 友元类:可以访问该类的私有成员;
Class Tv {
public:
friend class Romote; //Remote can access Tv private parts
...
}
class Romote {
...
void test(Tv & T) {
...
}
}
- 友元成员函数:只能通过友元成员函数访问该类的私有成员;
class Tv; //前向声明
class Remote {
...
};
class Tv {
friend void Remote::set_chan(Tv & t, int c); //友元成员函数,可以影响Tv的私有成员
...
private:
int channel;
};
//Remote methods as inline functions
...
inline Remote::set_chan(Tv & t, int c) {
t.channel = c;
}
- 互相友元类;
class Tv {
friend class Remote;
public:
void buzz(Remote & r);
...
};
class Remote {
friend class Tv;
...
};
inline void Tv::buzz(Remote & r) {
...
}
- 共同的友元;
class Analyzer;
class Probe {
friend void sync(Analyzer & a, const Probe &p); //sync a to p
friend void sync(Probe &p, const Analyzer & a); //sync p to a
...
};
class Analyzer{
friend void sync(Analyzer & a, const Probe &p); //sync a to p
friend void sync(Probe &p, const Analyzer & a); //sync p to a
...
};
//define
inline void sync(Analyzer & a, const Probe &p) {
...
}
inline void sync(Probe &p, const Analyzer & a) {
...
}
2.异常
- 可以使用abort()直接终止程序,或返回错误码errno;
- 使用try-catch块捕获异常,throw抛出异常;
- catch(...){//statements},省略号表示可以捕获任何异常;
- 基类对象可以捕获派生类对象异常,但派生类对象只能捕获派生类对象异常;
- exception类:头文件stdexcept定义了logic_error和runtime_error类,logic_error系列包含domain_error,invalid_argument,length_error和out_of_bounds等类型错误,runtime_error包含range_error、overflow和underflow等类型错误。
try {
...
} catch(out_of_bounds & oe) { //catch out_of_bounds error
...
} catch(logic_error & oe) { //catch remaining logic_error family
...
} catch(exception & oe) { //catch runtime_error, exception objects
...
}
- 包含new头文件,可以捕获bad_alloc异常;
- 未捕获异常和意外异常会导致调用terminate()接口,然后调用abort()终止程序;未捕获异常可以使用set_terminate()指定终止操作,意外异常可以使用set_unexpected()函数指定终止操作, set_unexpected使用更严格,指定的函数只能通过terminate()/abort()/exit()来终止程序,或者抛出异常。
#include <exception>
void myQuit() {
...
exit(5);
}
set_terminate(myQuit);
void myUnexpected() {
throw std::bad_exception(); //or just throw
}
set_unexpected(myUnexpected);
3.强制类型转换
- dynamic_cast:在类类型转换中,只有类型相同或发生向上转换(派生类转换为基类)时,才进行转换,否则将返回空指针。
class A {
...
}
class B : public A {
...
}
A *a;
B *b;
A *t = dynamic_cast<A *> b; //valid
B *t = dynamic_cast<B*> a; //invalid, return null
- const_cast: 一般指针不能指向const变量,因为不能修改const变量的值。但是通过const_cast强制转换后,可以临时更改const变量的值。
int a = 10;
const int b = 10;
const int * p1 = a;
const int * p2 = b;
int * p;
p = const_cast<int *> p1;
*p += 2; //p1指向的值改变,a也改变,即*p1 = 12, a = 12
p = const_cast<int *>p2;
*p += 2; //因为b也是const变量,所以b的值不变
- static_cast: 支持类对象的向上和向下转换。如果类型不一致则非法。
- reinterpret_cast: 支持更广泛的转换,比如指针转换为足以转换为指针表示的整形。
4.其他
- typeid运算符:确定两个对象是否未同种类型,同时typeid包含name()函数返回随实现而异的字符串--类型,定义位于typeinfo头文件中。
typeid(classname) == typeid(*pg);
cout << "Now processing type " << typeid(*pg).name() << endl;