c++编程基础个人笔记(五)--友元、异常和其他

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;
  •  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值