首页
关于
友链
留言
统计
Search
1
基于Rocky Linux 8.10系统使用源码搭建LNMP环境,附加安装SQLite
324 阅读
2
阿里云轻量应用服务器图文安装红帽系统RHEL8.10
73 阅读
3
.NET Framework
56 阅读
4
博客测试文章
33 阅读
5
VMware Workstation Pro
20 阅读
软件整理
C/C++学习笔记
Linux学习笔记
博客搭建
杂项
Search
标签搜索
Nginx
测试
LNMP
Typecho
红帽系统
Alpine Linux
GRUB
windows
PowerShell
MySQL
SQLite
PHP
Rocky Linux
HTTPS
SSL
Let's Encrypt
GDB
博客
Apache
SQLite3
hansyee
累计撰写
105
篇文章
累计收到
2
条评论
首页
栏目
软件整理
C/C++学习笔记
Linux学习笔记
博客搭建
杂项
页面
关于
友链
留言
统计
搜索到
105
篇与
的结果
2024-10-16
C++初学-模板编程的实例应用
背景说明以下程序整理于<>中的以template进行编程的篇章。主要实现了一个基础的二叉查找树。类的设计二叉树包含两个类:一个是 BinaryTree,用于存储一个指针,指向根节点;另一个是 BTnode,用来存储节点值,以及连接左右两个子节点。节点值的类型即为参数化的部分。其中 BinaryTree是提供给客户使用的类,包含以下可用操作:插入元素(insert)、移除元素(remove)、查找元素(find)、清除二叉树(clear)、打印二叉树(前序、中序、后序)。实现BinaryTree.h#ifndef BINARYTREE_H_INCLUDED #define BINARYTREE_H_INCLUDED #include <iostream> using uint_t = unsigned int; // 类模板前置声明 template <class elemType> class BinaryTree; template <class valType> class BTnode; template <class valType> class BTnode { friend class BinaryTree<valType>; public: // 普通构造函数,节点值为val BTnode(const valType &val); // 析构函数 ~BTnode(); // 插入一个新节点,节点值为val void insert_value(const valType &val); // 移除一个节点,节点值为val,父节点为prev void remove_value(const valType &val, BTnode * &prev); // 查找一个结点,节点值为val bool find_value(const valType &val) const; // 前序打印:节点本身-左子节点-右子节点 void preorder(BTnode *pt, std::ostream &os) const; // 中序打印:左子节点-节点本身-右子节点 void inorder(BTnode *pt, std::ostream &os) const; // 后序打印:左子节点-右子节点-节点本身 void postorder(BTnode *pt, std::ostream &os) const; // 获取节点值 const valType& value() const { return _val; } // 获取节点值出现次数 uint_t occurs() const { return _cnt; } // 遍历subtree节点下的左子树,将leaf接为最下层的叶子节点 static void lchild_leaf(BTnode *leaf, BTnode *subtree); private: // 拷贝构造函数 BTnode(const BTnode &rhs); // 赋值运算符重载函数 BTnode& operator=(const BTnode &rhs); // 打印节点值 void display_val(BTnode *pt, std::ostream &os) const; private: // 节点值 valType _val; // 节点值出现次数 uint_t _cnt; // 指向左子节点 BTnode *_lchild; // 指向右子节点 BTnode *_rchild; }; template <typename valType> inline BTnode<valType>:: BTnode(const valType& val) : _val(val), _cnt(1), _lchild(nullptr), _rchild(nullptr) { *(BinaryTree<valType>::getOutStream()) << "调用普通构造函数BTnode<valType>::BTnode(const valType& val)" << std::endl; } template <typename valType> inline BTnode<valType>:: BTnode(const BTnode &rhs) : _val(rhs._val), _cnt(1), _lchild(nullptr), _rchild(nullptr) { *(BinaryTree<valType>::getOutStream()) << "调用拷贝构造函数BTnode<valType>::BTnode(const BTnode &rhs)" << std::endl; } template <typename valType> inline BTnode<valType>& BTnode<valType>:: operator=(const BTnode &rhs) { _val = rhs._val; _cnt = 1; _lchild = nullptr; _rchild = nullptr; *(BinaryTree<valType>::getOutStream()) << "调用赋值运算符重载函数BTnode<valType>::BTnode(const BTnode &rhs)" << std::endl; } template <typename valType> inline BTnode<valType>:: ~BTnode() { *(BinaryTree<valType>::getOutStream()) << "调用析构函数BTnode<valType>::~BTnode()" << std::endl; } template <typename valType> void BTnode<valType>:: insert_value(const valType &val) { if (val == _val) { ++_cnt; return; } else if (val < _val) { if (_lchild) _lchild->insert_value(val); else _lchild = new BTnode(val); } else { if (_rchild) _rchild->insert_value(val); else _rchild = new BTnode(val); } } template <typename valType> void BTnode<valType>:: lchild_leaf(BTnode *leaf, BTnode *subtree) { while (subtree->_lchild) subtree = subtree->_lchild; subtree->_lchild = leaf; } template <typename valType> void BTnode<valType>:: remove_value(const valType &val, BTnode * &prev) { // 算法: // 以删除节点的右子节点取代删除节点本身 // 若无右子节点,就以左子节点取代删除节点本身 // 搬移左子节点,使其成为右子节点的左子树的叶节点 if (val == _val) { if (_rchild) { prev = _rchild; if (_lchild) { if (prev->_lchild) BTnode<valType>::lchild_leaf(_lchild, prev->_lchild); else prev->_lchild = _lchild; } } else { prev = _lchild; } delete this; } else if (val < _val) { if (_lchild) _lchild->remove_value(val, _lchild); } else { if (_rchild) _rchild->remove_value(val, _rchild); } } template <typename valType> bool BTnode<valType>:: find_value(const valType &val) const { if (val == _val) { return true; } else if (val < _val) { if (_lchild) return _lchild->find_value(val); else return false; } else { if (_rchild) return _rchild->find_value(val); else return false; } } template <typename valType> void BTnode<valType>:: preorder(BTnode *pt, std::ostream &os) const { if (pt) { // 节点本身-左子节点-右子节点 display_val(pt, os); if (pt->_lchild) preorder(pt->_lchild, os); if (pt->_rchild) preorder(pt->_rchild, os); } } template <typename valType> void BTnode<valType>:: inorder(BTnode *pt, std::ostream &os) const { if (pt) { // 左子节点-节点本身-右子节点 if (pt->_lchild) inorder(pt->_lchild, os); display_val(pt, os); if (pt->_rchild) inorder(pt->_rchild, os); } } template <typename valType> void BTnode<valType>:: postorder(BTnode *pt, std::ostream &os) const { if (pt) { // 左子节点-右子节点-节点本身 if (pt->_lchild) postorder(pt->_lchild, os); if (pt->_rchild) postorder(pt->_rchild, os); display_val(pt, os); } } template <typename valType> void BTnode<valType>:: display_val(BTnode *pt, std::ostream &os) const { if (pt) { os << pt->_val; if (pt->_cnt > 1) os << "(" << pt->_cnt << ") "; else os << ' '; } } template <class elemType> class BinaryTree { public: // 默认构造函数 BinaryTree(); // 拷贝构造函数 BinaryTree(const BinaryTree &rhs); // 赋值运算符重载函数 BinaryTree& operator=(const BinaryTree &rhs); // 析构函数 ~BinaryTree(); // 插入新节点,节点值为elem void insert(const elemType& elem); // 移除节点,节点值为elem void remove(const elemType &elem); // 查找节点是否在二叉树,节点值为val bool find(const elemType &val) const; // 二叉树是否为空 bool empty() { return (nullptr == _root); } // 清除整个二叉树 void clear() { clear(_root); _root = nullptr; } // 前序打印:节点本身-左子节点-右子节点 void preorder(std::ostream &os = *_current_os) const { _root->preorder(_root, os); os << std::endl; } // 中序打印:左子节点-节点本身-右子节点 void inorder(std::ostream &os = *_current_os) const { _root->inorder(_root, os); os << std::endl; } // 后序打印:左子节点-右子节点-节点本身 void postorder(std::ostream &os = *_current_os) const { _root->postorder(_root, os); os << std::endl; } // 获取当前输出流 static std::ostream* getOutStream() { return _current_os; } // 设置当前输出流 static void setOutStream(std::ostream *os) { if (os) _current_os = os; } private: // 将src指向的子树复制到tar指向的子树 void copy(BTnode<elemType> *&tar, const BTnode<elemType> *src); // 清除二叉树 void clear(BTnode<elemType> *pt); // 移除根节点 void remove_root(); private: // 指向二叉树根节点 BTnode<elemType> *_root; // 指向输出流 static std::ostream *_current_os; }; template <typename elemType> inline BinaryTree<elemType>:: BinaryTree() : _root(nullptr) { *_current_os << "调用默认构造函数BinaryTree<elemType>::BinaryTree()" << std::endl; } template <typename elemType> inline BinaryTree<elemType>:: BinaryTree(const BinaryTree &rhs) { copy(_root, rhs._root); *_current_os << "调用拷贝构造函数BinaryTree<elemType>::BinaryTree(const BinaryTree &rhs)" << std::endl; } template <typename elemType> inline BinaryTree<elemType>& BinaryTree<elemType>:: operator=(const BinaryTree &rhs) { if (this != &rhs) { clear(); copy(_root, rhs._root); } *_current_os << "调用赋值运算符重载函数BinaryTree<elemType>::operator=(const BinaryTree &rhs)" << std::endl; return *this; } template <typename elemType> inline BinaryTree<elemType>:: ~BinaryTree() { clear(); *_current_os << "调用析构函数BinaryTree<elemType>::~BinaryTree()" << std::endl; } template <typename elemType> void BinaryTree<elemType>:: insert(const elemType &elem) { if (_root) _root->insert_value(elem); else _root = new BTnode<elemType>(elem); } template <typename elemType> void BinaryTree<elemType>:: remove(const elemType &elem) { if (_root) { if (elem == _root->_val) remove_root(); else _root->remove_value(elem, _root); } } template <typename elemType> bool BinaryTree<elemType>:: find(const elemType &elem) const { if (_root) { return _root->find_value(elem); } else { return false; } } template <typename elemType> void BinaryTree<elemType>:: remove_root() { // 算法: // 以删除节点的右子节点取代删除节点本身 // 若无右子节点,就以左子节点取代删除节点本身 // 搬移左子节点,使其成为右子节点的左子树的叶节点 if (_root) { BTnode<elemType> * const oldroot = _root; if (oldroot->_rchild) { _root = oldroot->_rchild; BTnode<elemType> *oldlc = oldroot->_lchild; BTnode<elemType> *newlc = _root->_lchild; if (oldlc) { if (newlc) BTnode<elemType>::lchild_leaf(oldlc, newlc); else _root->_lchild = oldlc; } } else { _root = oldroot->_lchild; } delete oldroot; } } template <typename elemType> void BinaryTree<elemType>:: clear(BTnode<elemType> *pt) { if (pt) { clear(pt->_lchild); clear(pt->_rchild); delete pt; } } template <typename elemType> void BinaryTree<elemType>:: copy(BTnode<elemType> *&tar, const BTnode<elemType> *src) { if (src) { tar = new BTnode<elemType>(src->val); if (src->_lchild) copy(tar->_lchild, src->_lchild); if (src->_rchild) copy(tar->_rchild, src->_rchild); } } #endif // BINARYTREE_H_INCLUDEDmain.cpp#include "BinaryTree.h" #include <string> #include <fstream> template<typename elemType> std::ostream *BinaryTree<elemType>::_current_os = &std::cout; const std::string log_file = "logfile.txt"; int main() { std::ofstream log(log_file); if (!log) { std::cerr << "错误:无法打开文件[" << log_file << "]" << std::endl; return -1; } else { BinaryTree<std::string>::setOutStream(&log); } BinaryTree<std::string> bt; if (bt.empty()) { log << "二叉树为空" << std::endl; } else { log << "二叉树不为空" << std::endl; log << "前序: "; bt.preorder(log); log << "中序: "; bt.inorder(log); log << "后序: "; bt.postorder(log); } bt.insert("Piglet"); bt.insert("Eeyore"); bt.insert("Roo"); bt.insert("Tigger"); bt.insert("Chris"); bt.insert("Chris"); bt.insert("Chris"); bt.insert("Pooh"); bt.insert("Kanga"); log << "前序: "; bt.preorder(log); log << "中序: "; bt.inorder(log); log << "后序: "; bt.postorder(log); bt.remove("Piglet"); log << "前序: "; bt.preorder(log); log << "中序: "; bt.inorder(log); log << "后序: "; bt.postorder(log); bt.remove("Roo"); log << "前序: "; bt.preorder(log); log << "中序: "; bt.inorder(log); log << "后序: "; bt.postorder(log); if (bt.find("Kanga")) { log << "存在Kanga" << std::endl; } else { log << "不存在Kanga" << std::endl; } if (bt.find("hsy")) { log << "存在hsy" << std::endl; } else { log << "不存在hsy" << std::endl; } bt.clear(); if (bt.empty()) { log << "二叉树为空" << std::endl; } else { log << "二叉树不为空" << std::endl; bt.preorder(log); bt.inorder(log); bt.postorder(log); } return 0; }运行结果如下调用默认构造函数BinaryTree<elemType>::BinaryTree() 二叉树为空 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 调用普通构造函数BTnode<valType>::BTnode(const valType& val) 前序: Piglet Eeyore Chris(3) Kanga Roo Pooh Tigger 中序: Chris(3) Eeyore Kanga Piglet Pooh Roo Tigger 后序: Chris(3) Kanga Eeyore Pooh Tigger Roo Piglet 调用析构函数BTnode<valType>::~BTnode() 前序: Roo Pooh Eeyore Chris(3) Kanga Tigger 中序: Chris(3) Eeyore Kanga Pooh Roo Tigger 后序: Chris(3) Kanga Eeyore Pooh Tigger Roo 调用析构函数BTnode<valType>::~BTnode() 前序: Tigger Pooh Eeyore Chris(3) Kanga 中序: Chris(3) Eeyore Kanga Pooh Tigger 后序: Chris(3) Kanga Eeyore Pooh Tigger 存在Kanga 不存在hsy 调用析构函数BTnode<valType>::~BTnode() 调用析构函数BTnode<valType>::~BTnode() 调用析构函数BTnode<valType>::~BTnode() 调用析构函数BTnode<valType>::~BTnode() 调用析构函数BTnode<valType>::~BTnode() 二叉树为空 调用析构函数BinaryTree<elemType>::~BinaryTree()
2024年10月16日
3 阅读
0 评论
0 点赞
2024-10-11
C++初学-封装继承多态的实例应用
背景说明以下程序整理于<>中的面向对象编程风格的篇章,这个章节中展示的代码在某些地方其实是有问题的,例如有些常成员函数的声明其实是不能声明为常成员函数的,也可能是我理解不到位。不管怎样,本人结合作者的意图对其进行了部分修改做出一个能实际运行的程序就算成功。类的设计程序主要功能是计算出斐波那契数列某一位置的元素值,还包括其他一些基本功能,例如返回该数列是哪一种类型(此处只实现了斐波那契数列,实际数列有很多,可做引申)、数列的起始位置、数列的长度、可容纳元素的最大大小、打印数列所有元素。基类num_sequence.h#ifndef NUM_SEQUENCE_H_INCLUDED #define NUM_SEQUENCE_H_INCLUDED #include <iostream> #include <vector> #include <typeinfo> // 声明命名空间 namespace mycpp { // C++11支持使用using为类型取别名 // 可取代老式的typedef // typedef unsigned int uint_t; using uint_t = unsigned int; // 常量 const int * const NULLPTR = NULL; // 基类,抽象类(含有纯虚函数) class num_sequence { protected: // 默认构造函数 num_sequence(); // 构造函数 num_sequence(uint_t length, uint_t beg_pos, std::vector<uint_t> &relems); public: // 拷贝构造函数 num_sequence(const num_sequence &rhs); // 赋值运算符重载函数 // 返回引用可使用链式赋值同时避免构造临时对象,减少系统开销 num_sequence& operator=(const num_sequence &rhs); // 析构函数 // 基类的析构函数需要声明为虚函数 // 声明虚函数的目的是告诉编译器在运行时动态的根据基类指针实际指向的对象来执行相应的析构函数 // 未申明为虚函数的话,基类指针无论是否指向派生类,其析构函数都在编译期就被静态解析为基类的析构函数 virtual ~num_sequence(); public: // 返回数列类型名称 // 常成员函数(执行过程中不会改变对象) const char* what_am_i() const; // 返回pos上的元素 uint_t elem(uint_t pos); // 返回数列长度 //常成员函数(执行过程中不会改变对象) uint_t length() const; // 返回数列起始位置值 // 常成员函数(执行过程中不会改变对象) uint_t beg_pos() const; // 返回数列所支持的最大位置值 // 静态成员函数(所有类共享一份,并不专属于哪个类的对象) static uint_t max_elems(); // 将所有元素输出到os // 函数默认参数,默认为标准输出 // 返回引用可使用链式输出同时避免构造临时对象,减少系统开销 std::ostream& print(std::ostream &os = std::cout) const; protected: // 产生直到pos位置的元素 // 纯虚函数,基类没有实现的必要,仅提供接口,依赖派生类来实现 virtual void gen_elems(uint_t pos) = 0; // 检查pos位置是否为有效位置 bool check_integrity(uint_t pos); protected: // 数列长度 uint_t _length; // 数列起始位置,从1开始计数 uint_t _beg_pos; // 元素最大个数 // 静态成员、常量 // C++11支持常量表达式 static constexpr uint_t _max_elems = 1024; // 数列派生类的容器的引用 std::vector<uint_t> &_relems; }; // 内联函数(建议编译器在函数调用处直接展开,减少函数调用开销) inline uint_t num_sequence::length() const { return _length; } inline uint_t num_sequence::beg_pos() const { return _beg_pos; } inline uint_t num_sequence::max_elems() { return _max_elems; } inline std::ostream& operator<<(std::ostream &os, const num_sequence &ns) { return ns.print(os); } } // namespace mycpp #endif // NUM_SEQUENCE_H_INCLUDEDnum_sequence.cpp#include "num_sequence.h" // 使用命名空间 // using namespace mycpp; // 全局作用域 using mycpp::num_sequence; // 单个指定 using mycpp::uint_t; // 单个指定 // 构造函数使用初始化列表 // 这里_relems强行绑定了一个空对象,无实际意义,仅演示默认构造函数 // 1.无参的构造函数 // 2.全部参数都有默认参数的构造函数 // 3.未实现自定义构造函数时编译器会自动生成默认构造函数 num_sequence::num_sequence() : _length(1), _beg_pos(1), _relems((std::vector<uint_t>&)(*NULLPTR)) { std::cout << "调用构造函数num_sequence::num_sequence()" << std::endl; } // 构造函数使用初始化列表 num_sequence::num_sequence(uint_t length, uint_t beg_pos, std::vector<uint_t> &relems) : _length(length), _beg_pos(beg_pos), _relems(relems) { std::cout << "调用构造函数num_sequence::num_sequence(uint_t length, uint_t beg_pos, std::vector<uint_t> &relems)" << std::endl; } // 构造函数使用初始化列表 //num_sequence::num_sequence(const num_sequence &rhs) : // _length(rhs.length), // _beg_pos(rhs.beg_pos), // _relems(rhs.relems) // C++11支持构造函数使用委托构造 num_sequence::num_sequence(const num_sequence &rhs) : num_sequence(rhs._length, rhs._beg_pos, rhs._relems) { std::cout << "调用拷贝构造函数num_sequence::num_sequence(const num_sequence &rhs)" << std::endl; } num_sequence& num_sequence::operator=(const num_sequence &rhs) { if (this != &rhs) // 避免自我赋值 { _length = rhs._length; _beg_pos = rhs._beg_pos; _relems = rhs._relems; } std::cout << "调用赋值运算符重载函数num_sequence::operator=(const num_sequence &rhs)" << std::endl; return *this; } num_sequence::~num_sequence() { std::cout << "调用析构函数num_sequence::~num_sequence()" << std::endl; } const char* num_sequence::what_am_i() const { // typeid运算符允许在运行时确定对象的类型,可用来确定是基类还是派生类 // typeid运算符的返回值类型为const type_info& return typeid(*this).name(); } uint_t num_sequence::elem(uint_t pos) { if (!check_integrity(pos)) { return 0; } return _relems[(_beg_pos - 1) + (pos - 1)]; } std::ostream& num_sequence::print(std::ostream &os) const { os << "当前的数列元素:"; if (_relems.size()) { for (uint_t i = _beg_pos - 1; i < _beg_pos + _length - 1; i++) { os << _relems[i] << ' '; } } os << std::endl; return os; } bool num_sequence::check_integrity(uint_t pos) { if (pos <= 0 || pos > _max_elems) { std::cerr << "无效的位置:" << pos << "无法处理请求" << std::endl; return false; } if (pos > _relems.size()) { gen_elems(pos); } return true; }派生类fibonacci.h#ifndef FIBONACCI_H_INCLUDED #define FIBONACCI_H_INCLUDED #include "num_sequence.h" // 声明命名空间 namespace mycpp { // 派生类 class Fibonacci : public num_sequence { public: // 默认构造函数 // 无参或所有参数都有默认参数的构造函数 Fibonacci(uint_t length = 1, uint_t beg_pos = 1); // 拷贝构造函数 Fibonacci(const Fibonacci &rhs); // 赋值运算符重载函数 // 返回引用可使用链式赋值同时避免构造临时对象,减少系统开销 Fibonacci& operator=(const Fibonacci &rhs); // 析构函数 ~Fibonacci(); protected: // 产生直到pos位置的元素 // C++11支持使用override说明符指明该虚函数重写基类的虚函数 virtual void gen_elems(uint_t pos) override; protected: // 数列容器 // 静态成员变量(此处是声明,需要在类外定义) static std::vector<uint_t> _elems; }; // 内联函数(建议编译器在函数调用处直接展开,减少函数调用开销) // 构造函数使用初始化列表 // 此处使用基类的构造函数并不是委托构造 inline Fibonacci::Fibonacci(uint_t length, uint_t beg_pos) : num_sequence(length, beg_pos, _elems) { std::cout << "调用构造函数Fibonacci::Fibonacci(uint_t length, uint_t beg_pos)" << std::endl; } inline Fibonacci::Fibonacci(const Fibonacci &rhs) : num_sequence(rhs) { std::cout << "调用拷贝构造函数Fibonacci::Fibonacci(const Fibonacci &rhs)" << std::endl; } inline Fibonacci& Fibonacci::operator=(const Fibonacci &rhs) { if (this != &rhs) // 避免自我赋值 { // 明确调用基类的拷贝赋值函数 num_sequence::operator=(rhs); } std::cout << "调用赋值运算符重载函数Fibonacci& Fibonacci::operator=(const Fibonacci &rhs)" << std::endl; return *this; } inline Fibonacci::~Fibonacci() { std::cout << "调用析构函数Fibonacci::~Fibonacci()" << std::endl; } } // namespace mycpp #endif // FIBONACCI_H_INCLUDEDfibonacci.cpp#include "fibonacci.h" // 使用命名空间 // using namespace mycpp; // 全局作用域 using mycpp::num_sequence; // 单个指定 using mycpp::Fibonacci; // 单个指定 using mycpp::uint_t; // 单个指定 std::vector<uint_t> Fibonacci::_elems; void Fibonacci::gen_elems(uint_t pos) { // 首次生成数列元素 // 从_beg_pos开始的_length个数列元素 if (_elems.empty()) { _elems.push_back(1); _elems.push_back(1); uint_t end = _beg_pos + _length; uint_t i_2 = _elems[0]; uint_t i_1 = _elems[1]; for (uint_t i = 2 ; i < end; ++i) { uint_t elem = i_2 + i_1; _elems.push_back(elem); i_2 = i_1; i_1 = elem; } } // 继续生成不足pos位置的数列元素 if (_elems.size() < pos + _beg_pos) { uint_t end = _elems.size(); uint_t i_2 = _elems[end - 2]; uint_t i_1 = _elems[end - 1]; for (; end < pos + _beg_pos; ++end) { uint_t elem = i_2 + i_1; _elems.push_back(elem); _length++; i_2 = i_1; i_1 = elem; } } }测试程序main.cpp#include <iostream> #include "fibonacci.h" using namespace mycpp; int main() { std::cout << "sizeof(num_sequence)=" << sizeof(num_sequence) << std::endl; // sizeof(num_sequence)=24 std::cout << "sizeof(Fibonacci)=" << sizeof(Fibonacci) << std::endl; // sizeof(Fibonacci)=24 std::cout << "num_sequence::max_elems() = " << num_sequence::max_elems() << std::endl; // num_sequence::max_elems() = 1024 // error 不允许使用抽象类型的对象 // num_sequence *pbase = new num_sequence(); // 基类的指针指向派生类,可形成动态多态 num_sequence *pnum = new Fibonacci(10, 3); // 调用构造函数num_sequence::num_sequence(uint_t length, uint_t beg_pos, std::vector<uint_t> &relems) // 调用构造函数Fibonacci::Fibonacci(uint_t length, uint_t beg_pos) // RTTI(Run-Time Type Identification 运行时类型鉴定机制) if (typeid(*pnum) == typeid(Fibonacci)) { std::cout << "pnum指向的对象是Fibonacci类型" << std::endl; } else { std::cout << "pnum指向的对象是其他类型" << std::endl; } // pnum指向的对象是Fibonacci类型 if (dynamic_cast<Fibonacci *>(pnum)) { std::cout << "pnum指向的对象是Fibonacci类型" << std::endl; } else { std::cout << "pnum指向的对象是其他类型" << std::endl; } // pnum指向的对象是Fibonacci类型 // 强制转换,编译器无法确认是否安全,程序员需要明白这是在干什么 if (static_cast<Fibonacci *>(pnum)) { std::cout << "pnum指向的对象是Fibonacci类型" << std::endl; } else { std::cout << "pnum指向的对象是其他类型" << std::endl; } std::cout << "pnum->what_am_i() = " << pnum->what_am_i() << std::endl; // pnum->what_am_i() = N5mycpp9FibonacciE std::cout << "pnum->beg_pos() = " << pnum->beg_pos() << std::endl; // pnum->beg_pos() = 3 std::cout << "pnum->length() = " << pnum->length() << std::endl; // pnum->length() = 10 pnum->print(); // 当前的数列元素: std::cout << "pnum->elem(10) = " << pnum->elem(10) << std::endl; // pnum->elem(10) = 144 std::cout << "pnum->beg_pos() = " << pnum->beg_pos() << std::endl; // pnum->beg_pos() = 3 std::cout << "pnum->length() = " << pnum->length() << std::endl; // pnum->length() = 10 pnum->print(); // 当前的数列元素:2 3 5 8 13 21 34 55 89 144 std::cout << "pnum->elem(30) = " << pnum->elem(30) << std::endl; // pnum->elem(30) = 2178309 std::cout << "pnum->beg_pos() = " << pnum->beg_pos() << std::endl; // pnum->beg_pos() = 3 std::cout << "pnum->length() = " << pnum->length() << std::endl; // pnum->length() = 30 pnum->print(); // 当前的数列元素:2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 delete pnum; // 调用析构函数Fibonacci::~Fibonacci() // 调用析构函数num_sequence::~num_sequence() return 0; }
2024年10月11日
3 阅读
0 评论
0 点赞
2024-09-26
通信调试助手
官网地址中文网页: https://www.cmsoft.cn/resource/103.html下载地址版本平台架构链接备注5.0.14windowsx86/x64scomm5.0.14.zip 2024-09-26 21:38:01 星期四
2024年09月26日
3 阅读
0 评论
0 点赞
2024-09-25
Wireshark
官网地址英文网页: https://www.wireshark.org/下载地址https://1.na.dl.wireshark.org/https://2.na.dl.wireshark.org/版本平台架构链接备注4.4.0windowsx64Wireshark-4.4.0-x64.exe 4.4.0windowsarm64Wireshark-4.4.0-arm64.exe 4.4.0windowsx64WiresharkPortable64_4.4.0.paf.exe 4.4.0macOSarm64Wireshark 4.4.0 Arm 64.dmg 4.4.0macOSx64Wireshark 4.4.0 Intel 64.dmg 4.4.0源码 wireshark-4.4.0.tar.xz 4.2.7windowsx64Wireshark-4.2.7-x64.exe 4.2.7windowsarm64Wireshark-4.2.7-arm64.exe 4.2.7windowsx64WiresharkPortable64_4.2.7.paf.exe 4.2.7macOSarm64Wireshark 4.2.7 Arm 64.dmg 4.2.7macOSx64Wireshark 4.2.7 Intel 64.dmg 4.2.7源码 wireshark-4.2.7.tar.xz 3.6.24windowsx86Wireshark-win32-3.6.24.exe 3.6.24windowsx86Wireshark-win32-3.6.24.msi 3.6.24windowsx86WiresharkPortable32_3.6.24.paf.exe 3.6.24windowsx64Wireshark-win64-3.6.24.exe 3.6.24windowsx64Wireshark-win64-3.6.24.msi 3.6.24windowsx64WiresharkPortable64_3.6.24.paf.exe 3.6.24macOSx64Wireshark 3.6.24 Intel 64.dmg 3.6.24macOSarm64Wireshark 3.6.24 Arm 64.dmg 3.6.24源码 wireshark-3.6.24.tar.xz 2024-09-25 18:26:28 星期三
2024年09月25日
3 阅读
0 评论
0 点赞
2024-09-25
go
官网地址英文网页: https://go.dev/下载地址版本平台架构链接备注1.23.1linuxx86go1.23.1.linux-386.tar.gzSHA256:cdee2f4e2efa001f7ee75c90f2efc310b63346cfbba7b549987e9139527c6b171.23.1linuxx64go1.23.1.linux-amd64.tar.gzSHA256:49bbb517cfa9eee677e1e7897f7cf9cfdbcf49e05f61984a2789136de359f9bd1.23.1linuxarm64go1.23.1.linux-arm64.tar.gzSHA256:faec7f7f8ae53fda0f3d408f52182d942cc89ef5b7d3d9f23ff117437d4b2d2f1.23.1linuxarmv6go1.23.1.linux-armv6l.tar.gzSHA256:6c7832c7dcd8fb6d4eb308f672a725393403c74ee7be1aeccd8a443015df99de1.23.1windowsx86go1.23.1.windows-386.zipSHA256:ab866f47d7be56e6b1c67f1d529bf4c23331a339fb0785f435a0552d352cb2571.23.1windowsx86go1.23.1.windows-386.msiSHA256:369a17f0cfd29e5c848e58ffe0d772da20abe334d1c7ca01dbcd55bb3db0b4401.23.1windowsx64go1.23.1.windows-amd64.zipSHA256:32dedf277c86610e380e1765593edb66876f00223df71690bd6be68ee17675c01.23.1windowsx64go1.23.1.windows-amd64.msiSHA256:e99dac215ee437b9bb8f8b14bbfe0e8756882c1ed291f30818e8363bc9c047a51.23.1windowsarmgo1.23.1.windows-arm.zipSHA256:1a57615a09f13534f88e9f2d7efd5743535d1a5719b19e520eef965a634f8efb1.23.1windowsarmgo1.23.1.windows-arm.msiSHA256:23169c79dc6b54e0dffb25be6b67425ad9759392a58309bc057430a9bf4c8f6a1.23.1windowsarm64go1.23.1.windows-arm64.zipSHA256:64ad0954d2c33f556fb1018d62de091254aa6e3a94f1c8a8b16af0d3701d194e1.23.1windowsarm64go1.23.1.windows-arm64.msiSHA256:313e1a543931ad8735b4df8969e00f5f4c2ef07be21f54015ede961a70263d351.23.1macOSx64go1.23.1.darwin-amd64.tar.gzSHA256:488d9e4ca3e3ed513ee4edd91bef3a2360c65fa6d6be59cf79640bf840130a581.23.1macOSx64go1.23.1.darwin-amd64.pkgSHA256:dd9e772686ed908bcff94b6144322d4e2473a7dcd7c696b7e8b6d12f23c887fd1.23.1macOSarm64go1.23.1.darwin-arm64.tar.gzSHA256:e223795ca340e285a760a6446ce57a74500b30e57469a4109961d36184d3c05a1.23.1macOSarm64go1.23.1.darwin-arm64.pkgSHA256:be34b488157ec69d94e26e1554558219a2c90789bcb7e3686965a7f9c8cfcbe71.23.1源码 go1.23.1.src.tar.gzSHA256:6ee44e298379d146a5e5aa6b1c5b5d5f5d0a3365eabdd70741e6e21340ec3b0d2024-09-25 13:56:46 星期三
2024年09月25日
2 阅读
0 评论
0 点赞
2024-09-25
frp
官网地址中文网页: https://gofrp.org/zh-cn/项目地址: https://github.com/fatedier/frp下载地址版本平台架构链接备注0.60.0windowsx64frp_0.60.0_windows_amd64.tar.gz 0.60.0windowsarm64frp_0.60.0_windows_arm64.tar.gz 0.60.0linuxx64frp_0.60.0_linux_amd64.tar.gz 0.60.0linuxarmfrp_0.60.0_linux_arm.tar.gz 0.60.0linuxarmhffrp_0.60.0_linux_arm_hf.tar.gz 0.60.0linuxarm64frp_0.60.0_linux_arm64.tar.gz 0.60.0linuxloong64frp_0.60.0_linux_loong64.tar.gz 0.60.0linuxmipsfrp_0.60.0_linux_mips.tar.gz 0.60.0linuxmipslefrp_0.60.0_linux_mipsle.tar.gz 0.60.0linuxmips64frp_0.60.0_linux_mips64.tar.gz 0.60.0linuxmips64lefrp_0.60.0_linux_mips64le.tar.gz 0.60.0linuxriscv64frp_0.60.0_linux_riscv64.tar.gz 0.60.0macOSx64frp_0.60.0_darwin_amd64.tar.gz 0.60.0macOSarm64frp_0.60.0_darwin_arm64.tar.gz 0.60.0freebsdx64frp_0.60.0_freebsd_amd64.tar.gz 0.60.0androidarm64frp_0.60.0_android_arm64.tar.gz 0.51.3windowsx86frp_0.51.3_windows_386.tar.gz 0.51.3windowsx64frp_0.51.3_windows_amd64.tar.gz 0.51.3windowsarm64frp_0.51.3_windows_arm64.tar.gz 0.51.3linuxx86frp_0.51.3_linux_386.tar.gz 0.51.3linuxx64frp_0.51.3_linux_amd64.tar.gz 0.51.3linuxarmfrp_0.51.3_linux_arm.tar.gz 0.51.3linuxarm64frp_0.51.3_linux_arm64.tar.gz 0.51.3linuxmipsfrp_0.51.3_linux_mips.tar.gz 0.51.3linuxmipslefrp_0.51.3_linux_mipsle.tar.gz 0.51.3linuxmips64frp_0.51.3_linux_mips64.tar.gz 0.51.3linuxmips64lefrp_0.51.3_linux_mips64le.tar.gz 0.51.3linuxriscv64frp_0.51.3_linux_riscv64.tar.gz 0.51.3macOSx64frp_0.51.3_darwin_amd64.tar.gz 0.51.3macOSarm64frp_0.51.3_darwin_arm64.tar.gz 0.51.3freebsdx86frp_0.51.3_freebsd_386.tar.gz 0.51.3freebsdx64frp_0.51.3_freebsd_amd64.tar.gz 2024-09-25 13:34:35 星期三
2024年09月25日
3 阅读
0 评论
0 点赞
2024-09-25
百度网盘[BaiduNetdisk]
官网地址中文网页: https://pan.baidu.com/下载地址https://pan.baidu.com/download#win版本平台架构链接备注7.44.6.1windowsx86/x64BaiduNetdisk_7.44.6.1.exe 7.37.5.3windowsx86/x64BaiduNetdisk_7.37.5.3.exe 7.37.0.5windowsx86/x64BaiduNetdisk_7.37.0.5.exe 7.29.5.2windowsx86/x64BaiduNetdisk_7.29.5.2.exe 6.5.0.3windowsx86/x64BaiduNetdisk_6.5.0.3.exe最后一个无P2P共享版本4.17.7redhat系x64baidunetdisk_4.17.7_x86_64.rpm 4.17.7debian系x64baidunetdisk_4.17.7_amd64.deb 4.38.0macOSx64BaiduNetdisk_mac_4.38.0_x64.dmg 4.38.0macOSarm64BaiduNetdisk_mac_4.38.0_arm64.dmg 2024-09-25 12:21:52 星期三
2024年09月25日
3 阅读
0 评论
0 点赞
2024-09-25
Qalculate
官网地址英文网页: https://qalculate.github.io/项目地址: https://github.com/Qalculate/libqalculate/下载地址版本平台架构链接备注5.2.0windowsx86qalculate-5.2.0-i386.msi 5.2.0windowsx86qalculate-5.2.0-i386.zip 5.2.0windowsx64qalculate-5.2.0-x64.msi 5.2.0windowsx64qalculate-5.2.0-x64.msi 5.2.0linuxx64qalculate-5.2.0-x86_64.tar.xz 2024-09-25 12:11:57 星期三
2024年09月25日
1 阅读
0 评论
0 点赞
2024-09-25
PixPin
官网地址中文网页: https://pixpinapp.com/下载地址版本平台架构链接备注1.8.22windowsx86/x64PixPin_1.8.22.0.exe 1.8.22macOSx86/x64PixPin_1.8.22.0.dmg 2024-09-25 11:08:00 星期三
2024年09月25日
11 阅读
0 评论
0 点赞
2024-09-24
myBase
官网地址英文网页: https://www.wjjsoft.com/下载地址版本平台架构链接备注8.2.19windowsx64Mybase-Desktop-Ver8219-Win64.zipWindows 7+8.2.19linuxx64Mybase-Desktop-Ver8219-Linux-amd64.tar.xz 8.2.19macOSx64Mybase-Desktop-Ver8219-macOS.dmgmacOS 10.14+7.3.5windowsx86/x64myBase-Desktop-Ver735-Setup.zipWindows XP7.3.5linuxx64myBase-Desktop-Ver735-Linux-amd64.tar.bz2 7.3.5macOSx86/x64myBase-Desktop-Ver735-MacOSX.dmg10.10.x - 10.15.x7.3.5macOSx86/x64myBase-Desktop-Ver735f-MacOSX.dmg11 - 12.x Monterey8.1bwindowsx64Mybase-Server-Ver810b1-Win64.zipWindows 7+8.1blinuxx64Mybase-Server-Ver810b1-Linux-amd64.tar.xz 8.1blinuxarm64Mybase-Server-Ver810b1-Linux-aarch64.tar.xz 8.1bmacOSx64Mybase-Server-Ver810b1-macOS.dmgmacOS 10.14+2024-09-24 21:24:13 星期二
2024年09月24日
2 阅读
0 评论
0 点赞
1
2
3
...
11