C++模板与异常处理详解
立即解锁
发布时间: 2025-08-23 01:35:42 阅读量: 1 订阅数: 2 

# C++模板与异常处理详解
## 1. 函数模板输出运算符
为`BinaryTree`类模板提供输出运算符时,若为非模板类,可按如下方式编写:
```cpp
ostream& operator<<(ostream&, const int_BinaryTree&);
```
对于类模板,若为每个生成的类定义提供显式实例,会十分繁琐且永无止境。更好的解决方案是将输出运算符定义为函数模板:
```cpp
template <typename elemType>
inline ostream&
operator<<(ostream &os, const BinaryTree<elemType> &bt)
{
os << "Tree: " << endl;
bt.print(os);
return os;
}
```
当执行以下代码时:
```cpp
BinaryTree< string > bts;
cout << bts << endl;
```
会生成支持`BinaryTree<string>`作为第二个参数的输出运算符实例。同理,对于`BinaryTree<int>`也会生成相应实例。
`print()`是`BinaryTree`类模板的私有成员函数,为使输出运算符能访问`print()`,需将其声明为`BinaryTree`的友元:
```cpp
template <typename elemType>
class BinaryTree {
friend ostream& operator<<(ostream&,
const BinaryTree<elemType>&);
// ...
};
```
## 2. 常量表达式与默认参数
模板参数不仅限于类型,还可以是常量表达式。例如,可将数值序列类层次结构重新定义为模板类,使对象包含的元素数量参数化:
```cpp
template <int len>
class num_sequence {
public:
num_sequence(int beg_pos=1);
// ...
};
template <int len>
class Fibonacci : public NumericSeries<len> {
public:
Fibonacci(int beg_pos=1)
: num_sequence<len>(beg_pos){}
// ...
};
```
创建`Fibonacci`对象时,如:
```cpp
Fibonacci< 16 > fib1;
Fibonacci< 16 > fib2(17);
```
会生成`Fibonacci`派生类和`num_sequence`基类的实例,且`len`绑定为16。也可同时对长度和起始位置进行参数化:
```cpp
template < int len, int beg_pos >
class NumericSeries;
```
由于多数类对象从位置1开始,可提供位置的默认值:
```cpp
template <int len, int beg_pos=1>
class Fibonacci : public num_sequence<len,beg_pos>
{ ... };
```
以下是这些类对象的定义示例:
```cpp
num_sequence<32> *pns1to32 = new Fibonacci<32>;
num_sequence<32,33> *pns33to64 = new Fibonacci<32,33>;
```
默认参数值从右到左按位置解析。以下是重新定义的`num_sequence`和`Fibonacci`类:
```cpp
template <int len, int beg_pos>
class num_sequence {
public:
virtual ~num_sequence(){};
int elem(int pos) const;
const char* what_am_i() const;
static int max_elems(){ return _max_elems; }
ostream& print(ostream &os = cout) const;
protected:
virtual void gen_elems(int pos) const = 0;
bool check_integrity(int pos, int size) const;
num_sequence(vector<int> *pe) : _pelems(pe){}
static const int _max_elems = 1024;
vector<int> *_pelems;
};
template <int len, int beg_pos> ostream&
operator<<(ostream &os, const num_sequence<len,beg_pos> &ns)
{ return ns.print(os); }
template <int len, int beg_pos>
int num_sequence<len,beg_pos>::
elem(int pos) const
{
if (! check_integrity(pos, _pelems->size()))
return 0;
return (*_pelems)[pos-1];
}
template <int length, int beg_pos>
const char* num_sequence<length, beg_pos>::
what_am_i() const
{ return typeid(*this).name(); }
template <int length, int beg_pos>
bool num_sequence<length, beg_pos>::
check_integrity(int pos, int size) const
{
if (pos <= 0 || pos > max_elems()){
cerr << "!! invalid position: " << pos
<< " Cannot honor request\n";
return false;
}
if (pos > size) gen_elems(pos);
return true;
}
template <int length, int beg_pos>
ostream& num_sequence<length, beg_pos>::
print(ostream &os) const
{
int elem_pos = beg_pos-1;
int end_pos = elem_pos + length;
if (! check_integrity(end_pos, _pelems->size()))
return os;
os << "("
<< beg_pos << " , "
<< length << ") ";
while (elem_pos < end_pos)
os << (*_pelems)[elem_pos++] << ' ';
return os;
}
template <int length, int beg_pos=1>
class Fibonacci : public num_sequence<length, beg_pos> {
public:
Fibonacci() : num_sequence<length,beg_pos>(&_elems){}
protected:
virtual void gen_elems(int pos) const;
static vector<int> _elems;
};
template <int length, int beg_pos>
vector<int> Fibonacci<length,beg_pos>::_elems;
template <int length, int beg_pos>
void Fibonacci<length,beg_pos>::
gen_elems(int pos) const
{
if (pos <= 0 || pos > max_elems())
return;
if (_elems.empty())
{
_elems.push_back(1);
_elems.push_back(1);
}
if (_elems.size() < pos)
{
int ix = _elems.size();
int n_2 = _elems[ix-2],
n_1 = _elems[ix-1];
int elem;
for (; ix < pos; ++ix)
{
elem = n_2 + n_1;
_elems.push_back(elem);
n_2 = n_1; n_1 = elem;
}
}
}
```
以下是一个测试程序:
```cpp
int main()
{
Fibonacci<8> fib1;
Fibonacci<8,8> fib2;
Fibonacci<12,8> fib3;
cout << "fib1: " << fib1 << '\n'
<< "fib2: " << fib2 << '\n'
<< "fib3: " << fib3 << endl;
```
0
0
复制全文
相关推荐










