建立一个继承体系,List 是基类,ArrayList 和 LinkedList 是其派生类。并且编写实现下述函数并达到如下效果。 ostream& operator << (ostream&os, const List&rhs); 做一个流输出运算符重载,其第二个参数是List的常引用类型。我们知道子类的对象天生可以作为父类类型使用,因此 ArrayList a; LinkedList b; operator << (cout,a); operator << (cout,b); 这上面的调用显然都是合法的。但是现在要求实现如下效果:第 3 行的函数执行的是适合 ArrayList 输出的代码,而第 4 行执行的是适合 LinkedList 输出的代码。即,虽然调用的函数一样,但需要根据当时的实参类型选择合适的实现。相当于对非成员函数做到动态绑定。 相关知识 前面说过,虚函数可以实现动态绑定。也就是: class List{ public: virtual void disp(ostream&os)const; }; class ArrayList : public List{ public: void disp(ostream&os)const{/*这里是ArrayList的实现*/} } class LinkedList : public List{ public: void disp(ostream&os)const{/*这里是LinkedList的实现*/} } List *p = new ArrayList; p->disp(cout);//此时调用的是ArrayList的disp函数 delete p; p = new LinkedList; p->disp(cout);//此时调用的是LinkedList的disp函数 delete p; 如果是非成员函数,能不能实现类似效果呢?即 ostream& operator << (ostream&os, const List&rhs); ostream& operator << (ostream&os, const ArrayList&rhs); ostream& operator << (ostream&os, const LinkedList&rhs); List *p = new ArrayList; cout<<*p<<endl;//此时希望调用的是operator<<(ostream,ArrayList&) delete p; p = new LinkedList; cout<<*p<<endl;//此时希望调用的是operator<<(ostream,LinkedList&) delete p; 遗憾的是,非成员函数不具备这样的功能。对于上述流输出运算符调用而言,它的实参会被看作是 List 类型,因此只会调用上文中的第一个重载函数。而不会根据 p 实际指向的类型动态调用其他流输出重载函数。 如何令非成员函数也体现出动态绑定的特性呢?答案是通过成员函数,而不是通过函数重载。例如,可以这样实现流输出运算符重载: ostream& operator << (ostream&os,const List&rhs){ rhs.disp(os); return os; } /************************************************** *这里不再需要实现 * ostream& operator << (ostream&os, const List&rhs); *和 * ostream& operator << (ostream&os, const List&rhs); *等函数 *****************************************************/ 编程要求 根据提示,在右侧编辑器的Begin-End区域内补充代码。 测试说明 本关共有 8 个文件。其中 List.h 定义了 List 类及其成员函数。ListOp.h 和 ListOp.cpp 定义了与 List 相关的运算符重载。ArrayList.h 和 ArrayList.cpp 定义了 ArrayList 类及其成员函数。LinkedList.h 和 LinkedList.cpp 定义了 LinkedList 类及其成员函数。main.cpp 定义了主函数。 用户的任务是编写 List.h、ArrayList.cpp 和 LinkedList.cpp 文件,以使得 main.cpp 正确运行。 List.h 内容如下: #ifndef _LIST_H_ #define _LIS
时间: 2025-05-24 07:09:14 浏览: 43
### 成员函数实现非成员函数动态绑定的方法
在C++中,可以通过友元函数或者将操作符重载为类的成员函数来实现非成员函数的动态绑定。对于流插入运算符 `<<` 的动态绑定需求,通常的做法是将其作为非成员函数进行重载,并利用基类中的虚成员函数完成多态行为。
以下是具体实现方式:
#### 实现思路
1. **定义虚成员函数**
在基类 `List` 中定义一个虚成员函数(如 `print()` 或者类似的名称),用于提供子类特定的行为。
2. **重载流插入运算符**
将流插入运算符 `<<` 定义为非成员函数,并在其内部调用基类的虚成员函数以实现动态绑定[^1]。
3. **派生类覆盖虚函数**
派生类 `ArrayList` 和 `LinkedList` 覆盖基类的虚函数,从而根据实际对象类型执行不同的输出逻辑。
#### 示例代码
以下是一个完整的示例代码展示如何实现这一目标:
```cpp
#include <iostream>
#include <string>
class List {
public:
virtual ~List() {} // 虚析构函数确保正确释放资源
virtual std::ostream& print(std::ostream&) const = 0; // 纯虚函数,强制派生类实现
friend std::ostream& operator<<(std::ostream&, const List&);
};
// 流插入运算符重载为非成员函数
std::ostream& operator<<(std::ostream& os, const List& list) {
return list.print(os); // 动态绑定到具体的派生类实现
}
class ArrayList : public List {
private:
int size;
public:
ArrayList(int s) : size(s) {}
std::ostream& print(std::ostream& os) const override { // 覆盖基类的虚函数
os << "This is an ArrayList with size: " << size;
return os;
}
};
class LinkedList : public List {
private:
std::string type;
public:
LinkedList(const std::string& t) : type(t) {}
std::ostream& print(std::ostream& os) const override { // 覆盖基类的虚函数
os << "This is a LinkedList of type: " << type;
return os;
}
};
int main() {
List* list1 = new ArrayList(10);
List* list2 = new LinkedList("Doubly");
std::cout << *list1 << std::endl; // 输出 ArrayList 特定的内容
std::cout << *list2 << std::endl; // 输出 LinkedList 特定的内容
delete list1;
delete list2;
return 0;
}
```
#### 关键点解析
1. 基类 `List` 提供了一个纯虚函数 `print()`,这使得任何派生类都必须实现自己的版本。
2. 运算符 `<<` 是非成员函数,但它通过调用基类的虚函数实现了动态绑定[^2]。
3. 派生类 `ArrayList` 和 `LinkedList` 各自提供了不同功能的具体实现,满足了多态的要求。
---
###
阅读全文
相关推荐
















