IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Essential C++学习笔记及源代码(第5章 面向对象编程风格) -> 正文阅读

[C++知识库]Essential C++学习笔记及源代码(第5章 面向对象编程风格)

第5章介绍了C++语言中使用Class进行类与类之间面向对象的编程的方式

导言:单纯的以对象为基础(object-based)的类机制无法针对同一种类之间的共通性质进行系统化的划分。因为这种单纯地以对象为基础的模型无法让我们更进一步地指出类间的关系。类与类之间的关系要使用面向对象编程模型(object-oriented programming model)加以设定。

面向对象编程概念的2项最主要的特质是:继承和多态。前者使我们得以将一群相关的类组织起来,并让我们得以分享其间的共通数据和操作行为,后者让我们在这些类之上进行编程时可以如同操控单一个体,而非相互独立的类,并赋予我们更多弹性来加入或移除任何特定类。

本章作者使用了一个LibMat类来模拟一个抽象基类并以此为基类派生出多个不同的基类,并教导读者在实现继承时父类和子类之间的构造函数和析构函数之间的先后调用关系。后用了一个sequence类派生出多个不同的数列类来模拟多态之间的应用,并且详细地说明了多态指针的应用。

附上笔者所写的课后练习答案。

//ch5_main.cpp

#include <iostream>
#include <string>
using namespace std;

class LibMat
{
public:
    LibMat() { cout << "LibMat::LibMat() default constructor!\n"; }
    virtual ~LibMat() { cout << "LibMat::~LibMat() destructor!\n"; }
    virtual void print() const { cout << "LibMat::print() -- I am a LibMat object!\n"; }
};

class Book : public LibMat
{
public:
    Book(const string &title, const string &author) : _title(title), _author(author)
    {
        cout << "Book::Book(" << _title;
        cout << ", " << _author << ")  constructor\n";
    }
    ~Book() { cout << "Book::~Book() destructor!\n"; }
    virtual void print() const //虚函数重写父类方法;
    {
        cout << "Book::print() -- I am a Book object!\n";
        cout << "My title is: " << _title << '\n';
        cout << "My author is: " << _author << endl;
    }
    const string &title() const { return _title; }
    const string &author() const { return _author; }

protected:
    string _title;
    string _author;
};

class AudioBook : public Book
{
public:
    AudioBook(const string &title, const string &author, const string &narrator)
        : Book(title, author), _narrator(narrator) //先使用父类的构造函数初始化父类成员后再初始化自身成员;
    {
        cout << "AudioBook::AudioBook(" << _title;
        cout << ", " << _author;
        cout << ", " << _narrator;
        cout << ")  constructor\n";
    }
    ~AudioBook() { cout << "AudioBook::~AudioBook() destructor!\n"; }
    virtual void print() const //虚函数重写父类方法;
    {
        cout << "AudioBook::print() -- I am a AudioBook object!\n";
        cout << "My title is: " << _title << '\n';
        cout << "My author is: " << _author << '\n';
        cout << "My narrator is: " << _narrator << endl;
    }
    const string &narrator() const { return _narrator; }

protected:
    string _narrator;
};

void print(const LibMat &mat)
{
    cout << "in global print(): about to print mat.print()\n";
    mat.print();
}

int main()
{
    //使用花括号可以看到析构函数被调用后的情况;
    {
        cout << "\nCreating a LibMat object to print()\n";
        LibMat m;
        print(m);
    }
    {
        cout << "\nCreating a Book object to print()\n";
        Book b("The Castle", "Franz Kafka");
        print(b);
    }
    {
        cout << "\nCreating a AudioBook object to print()\n";
        AudioBook ab("Man Without Qualities", "Robert Musil", "Kenneth Meyer");
        print(ab);
    }
    return 0;
}

//-----------------------------------------------------

//sequence.cpp

#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
#include <algorithm>
using namespace std;

class num_sequence
{
public:
    typedef vector<unsigned int>::iterator iterator;
    iterator begin() const { return _relems.begin() + _beg_pos - 1; }
    iterator end() const { return _relems.begin() + _beg_pos + _length; }

    virtual ~num_sequence() {}
    virtual num_sequence *clone() const = 0;

    unsigned int elem(int pos) const; //获取指定位置的元素;
    bool is_elem(unsigned int) const; //判断指定元素是否存在于数列中;
    int pos_elem(unsigned int) const; //获取指定区间元素个数;

    const char *what_am_i() const;
    static int max_elems() { return _max_elems; }
    ostream &print(ostream &os = cout) const;

    int length() const { return _length; }
    int beg_pos() const { return _beg_pos; }

    void set_position(int pos); //设置数列起始位置;
    void set_length(int pos);   //设置数列长度;

    bool operator==(const num_sequence &) const; //重载'=='运算符能够进行数列对象的比较;
    bool operator!=(const num_sequence &) const; //使用'=='运算符来重载'!='运算符;

    const vector<unsigned int> *sequence() const { return &_relems; }

protected:
    num_sequence(int, int, vector<unsigned int> &);
    enum
    {
        _max_elems = 1024
    };
    virtual void gen_elems(int pos) const = 0;
    int _calc_pos(unsigned int elem) const; //产生元素直到pos位置;
    bool check_integrity(int pos, int size) const;
    int _length;
    int _beg_pos;
    vector<unsigned int> &_relems;
};

ostream &operator<<(ostream &os, const num_sequence &ns)
{
    return ns.print(os);
}

inline bool num_sequence::operator==(const num_sequence &rhs) const
{
    return _beg_pos == rhs._beg_pos && _length == rhs._length;
}

inline bool num_sequence::operator!=(const num_sequence &rhs) const
{
    return !(*this == rhs);
}

inline void num_sequence::set_position(int pos)
{
    if (pos <= 0 || pos > _max_elems)
    {
        cerr << "!! invalid position: " << pos;
        cerr << " setting pos to default value of 1\n";
        cerr << "If inadequate, invoke set_position(pos)\n";
        pos = 1;
    }
    _beg_pos = pos;
    return;
}

inline void num_sequence::set_length(int len)
{
    if (len <= 0 || len + _beg_pos - 1 > _max_elems)
    {
        cerr << "!! invalid length for this object: " << len;
        cerr << " setting length to default value of 1\n";
        cerr << "If inadequate, invoke set_length(len)\n";
        len = 1;
    }
    _length = len;
    return;
}

inline num_sequence::num_sequence(int beg_pos, int len, vector<unsigned int> &re) : _relems(re)
{
    set_position(beg_pos);
    set_length(len);
}

inline unsigned int num_sequence::elem(int pos) const
{
    return !check_integrity(pos, _relems.size()) ? 0 : _relems[pos - 1];
}

inline const char *num_sequence::what_am_i() const
{
    return typeid(*this).name();
}

inline bool num_sequence::check_integrity(int pos, int size) const
{
    bool status = true;
    if (pos <= 0 || pos > _max_elems)
    {
        cerr << "!! invalid position: " << pos;
        cerr << " Cannot honor request\n";
        status = false;
    }
    else if (pos > size)
    {
        gen_elems(pos); //动态绑定来生成指定数列的元素;
    }
    return status;
}

inline bool num_sequence::is_elem(unsigned int elem) const
{
    //检查是否是数列中指定区间的元素, 若参数有误则返回false, 否则在数列中找此元素并返回结果;
    return !check_integrity(_beg_pos, _length) ? false : binary_search(begin(), end(), elem);
}

ostream &num_sequence::print(ostream &os) const
{
    int elem_pos = _beg_pos - 1;
    int end_pos = elem_pos + _length;

    if (!check_integrity(end_pos, _relems.size()))
    {
        return os;
    };
    os << "(" << _beg_pos << " , ";
    os << _length << ") ";
    while (elem_pos < end_pos)
    {
        os << _relems[elem_pos++] << ' ';
    }
    return os;
}

int num_sequence::pos_elem(unsigned int elem) const
{
    cout << "pos_elem( " << elem << " )\n";
    if (_relems[_relems.size() - 1] < elem)
    {
        return _calc_pos(elem);
    }
    iterator iter = find(_relems.begin(), _relems.end(), elem);
    return iter == _relems.end() ? 0 : distance(_relems.begin(), iter) + 1; //返回数列中区间元素的个数;
}

int num_sequence::_calc_pos(unsigned int elem) const
{
    int pos = _relems.size() - 1;

    cout << "calc_pos invoked()!: elem: " << elem;
    cout << " pos: " << pos;
    cout << " at: " << _relems[pos];
    cout << "\n";
    while (pos < _max_elems && _relems[pos] < elem)
    {
        gen_elems(++pos); //动态绑定生成新元素;
        cout << "pos: " << pos;
        cout << " at: " << _relems[pos] << endl;
    }
    return (pos < _max_elems && _relems[pos] == elem) ? pos + 1 : 0;
}

class Fibonacci : public num_sequence
{
public:
    Fibonacci(int beg_pos = 1, int len = 1) : num_sequence(beg_pos, len, _elems) {}
    virtual num_sequence *clone() const { return new Fibonacci(*this); }

protected:
    virtual void gen_elems(int pos) const;
    static vector<unsigned int> _elems;
};

class Pell : public num_sequence
{
public:
    Pell(int beg_pos = 1, int len = 1) : num_sequence(beg_pos, len, _elems) {}
    virtual num_sequence *clone() const { return new Pell(*this); }

protected:
    virtual void gen_elems(int pos) const;
    static vector<unsigned int> _elems;
};

class Lucas : public num_sequence
{
public:
    Lucas(int beg_pos = 1, int len = 1) : num_sequence(beg_pos, len, _elems) {}
    virtual num_sequence *clone() const { return new Lucas(*this); }

protected:
    virtual void gen_elems(int pos) const;
    static vector<unsigned int> _elems;
};

class Triangular : public num_sequence
{
public:
    Triangular(int beg_pos = 1, int len = 1) : num_sequence(beg_pos, len, _elems) {}
    virtual num_sequence *clone() const { return new Triangular(*this); }

protected:
    virtual void gen_elems(int pos) const;
    static vector<unsigned int> _elems;
};

class Square : public num_sequence
{
public:
    Square(int beg_pos = 1, int len = 1) : num_sequence(beg_pos, len, _elems) {}
    virtual num_sequence *clone() const { return new Square(*this); }

protected:
    virtual void gen_elems(int pos) const;
    static vector<unsigned int> _elems;
};

class Pentagonal : public num_sequence
{
public:
    Pentagonal(int beg_pos = 1, int len = 1) : num_sequence(beg_pos, len, _elems) {}
    virtual num_sequence *clone() const { return new Pentagonal(*this); }

protected:
    virtual void gen_elems(int pos) const;
    static vector<unsigned int> _elems;
};

inline void display(ostream &os, const num_sequence &ns, int pos, int elem_val)
{
    os << "The element at position " << pos;
    os << " for the ";
    os << ns.what_am_i();
    os << " sequence is " << elem_val << endl;
    return;
}

inline void display(ostream &os, const num_sequence &ns, int pos)
{
    os << "The element at position ";
    os << pos << " for the ";
    os << ns.what_am_i() << " sequence is ";
    os << ns.elem(pos) << endl;
    return;
}

void prog1()
{
    const int pos = 8;
    cout << "Test1:" << endl;

    Fibonacci fib;
    display(cout, fib, pos);

    Pell pell;
    display(cout, pell, pos);

    Lucas lucas;
    display(cout, lucas, pos);

    Triangular trian;
    display(cout, trian, pos);

    Square square;
    display(cout, square, pos);

    Pentagonal penta;
    display(cout, penta, pos);
    return;
}

void prog2()
{
    Fibonacci fib(1, 8);
    Pell pell(4, 6);
    Lucas lucas(7, 10);
    Triangular trian(1, 12);
    Square square(6, 6);
    Pentagonal penta(1, 8);

    cout << "\nTest2:" << endl;
    cout << "fib:\t" << fib << '\n';
    cout << "pell:\t" << pell << '\n';
    cout << "lucas:\t" << lucas << '\n';
    cout << "trian:\t" << trian << '\n';
    cout << "square:\t" << square << '\n';
    cout << "penta:\t" << penta << endl;
    return;
};

void prog3()
{
    num_sequence *pns = nullptr;
    int elem_val = 0;
    const int pos = 8;
    const int find_pos = 14;

    int elem_values[6] = {377, 80782, 843, 105, 196, 287};
    cout << "\nTest3:" << endl;
    //使用多态指针来模拟子类的操作;
    for (int ix = 0; ix < 6; ++ix)
    {
        switch (ix)
        {
        case 0:
            pns = new Fibonacci(1, 8);
            break;
        case 1:
            delete pns;
            pns = new Pell(1, 8);
            break;
        case 2:
            delete pns;
            pns = new Lucas(1, 8);
            break;
        case 3:
            delete pns;
            pns = new Triangular(1, 8);
            break;
        case 4:
            delete pns;
            pns = new Square(1, 8);
            break;
        case 5:
            delete pns;
            pns = new Pentagonal(1, 8);
            break;
        default:
            delete pns;
            return;
        }
        elem_val = pns->elem(pos);
        display(cout, *pns, pos, elem_val);
        cout << pns->what_am_i() << " : ( ";
        cout << pns->beg_pos() << ", ";
        cout << pns->length() << " ) : ";
        cout << *pns << endl;

        pns->set_length(12);
        cout << *pns << endl;
        cout << "num_sequence::is_elem() ";
        if (!pns->is_elem(elem_val) || pns->is_elem(2 * elem_val))
        {
            cout << "failed\n";
        }
        else
        {
            cout << "ok!\n";
        }
        cout << "copy constructor and equality ";
        num_sequence *pns2 = pns->clone(); //使用复制函数来构造一个新的与原先相同的数列;
        if (*pns != *pns2)
        {
            cout << "failed!\n";
        }
        else
        {
            cout << "ok!\n";
        }

        pns2->set_position(5);
        int posit = pns->pos_elem(elem_val);
        if (pns->pos_elem(elem_val) != pos)
        {
            cout << "pos_elem() failed : " << posit << "\n";
        }
        else
        {
            cout << "pos_elem() -- ok: " << posit << "\n";
        }
        posit = pns->pos_elem(elem_values[ix]);
        if (posit != find_pos)
        {
            cout << "pos_elem(): not found but grown: failed: ";
            cout << posit << " correct: " << find_pos << "\n";
        }
        else
        {
            cout << "pos_elem(): not found but grown: ok\n";
        }
        cout << "about to print final ns vector: \n";
        pns->print();
        cout << endl;

        cout << "ns2: should begin at position 5:\n";
        cout << *pns2 << endl;
    }
    return;
}

vector<unsigned int> Fibonacci::_elems;
vector<unsigned int> Pell::_elems;
vector<unsigned int> Lucas::_elems;
vector<unsigned int> Triangular::_elems;
vector<unsigned int> Square::_elems;
vector<unsigned int> Pentagonal::_elems;

void Fibonacci::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];
        int n_1 = _elems[ix - 1];
        for (int elem; ix <= pos; ++ix)
        {
            elem = n_2 + n_1;
            _elems.push_back(elem);
            n_2 = n_1;
            n_1 = elem;
        }
    }
    return;
}

void Pell::gen_elems(int pos) const
{
    if (pos <= 0 || pos > max_elems())
    {
        return;
    }
    if (_elems.empty())
    {
        _elems.push_back(1);
        _elems.push_back(2);
    }
    if (_elems.size() <= pos)
    {
        int ix = _elems.size();
        int n_2 = _elems[ix - 2];
        int n_1 = _elems[ix - 1];
        for (int elem; ix <= pos; ++ix)
        {
            elem = n_2 + 2 * n_1;
            _elems.push_back(elem);
            n_2 = n_1;
            n_1 = elem;
        }
    }
    return;
}

void Lucas::gen_elems(int pos) const
{
    if (pos <= 0 || pos > max_elems())
    {
        return;
    }
    if (_elems.empty())
    {
        _elems.push_back(1);
        _elems.push_back(3);
    }
    if (_elems.size() <= pos)
    {
        int ix = _elems.size();
        int n_2 = _elems[ix - 2];
        int n_1 = _elems[ix - 1];
        for (int elem; ix <= pos; ++ix)
        {
            elem = n_2 + n_1;
            _elems.push_back(elem);
            n_2 = n_1;
            n_1 = elem;
        }
    }
    return;
}

void Triangular::gen_elems(int pos) const
{
    if (pos <= 0 || pos > max_elems())
    {
        return;
    }
    if (_elems.size() <= pos)
    {
        int end_pos = pos + 1;
        for (int ix = _elems.size() + 1; ix <= end_pos; ++ix)
        {
            _elems.push_back(ix * (ix + 1) / 2);
        }
    }
    return;
}

void Square::gen_elems(int pos) const
{
    if (pos <= 0 || pos > max_elems())
    {
        return;
    }
    if (_elems.size() <= pos)
    {
        int end_pos = pos + 1;
        for (int ix = _elems.size() + 1; ix <= end_pos; ++ix)
        {
            _elems.push_back(ix * ix);
        }
    }
    return;
}

void Pentagonal::gen_elems(int pos) const
{
    if (pos <= 0 || pos > max_elems())
    {
        return;
    }
    if (_elems.size() <= pos)
    {
        int end_pos = pos + 1;
        for (int ix = _elems.size() + 1; ix <= end_pos; ++ix)
        {
            _elems.push_back(ix * (3 * ix - 1) / 2);
        }
    }
    return;
}

int main()
{
    prog1();
    prog2();
    prog3();

    return 0;
}

//-----------------------------------------------------

//Practise5.1.cpp

#include <iostream>
#include <vector>
#include <string>
using namespace std;

typedef string elemtype;
class Stack
{
public:
    virtual ~Stack() {}
    virtual bool pop(elemtype &elem) = 0;
    virtual bool push(const elemtype &elem) = 0;
    virtual bool peek(int index, elemtype &elem) = 0;
    virtual int top() const = 0;
    virtual int size() const = 0;
    virtual bool empty() const = 0;
    virtual bool full() const = 0;
    virtual void print(ostream &os = cout) const = 0;
};

ostream &operator<<(ostream &os, const Stack &rhs)
{
    rhs.print();
    return os;
}

class LIFO_Stack : public Stack
{
private:
    vector<elemtype> st;

public:
    LIFO_Stack(int capacity = 0) { st.reserve(capacity); }
    virtual ~LIFO_Stack() {}
    bool pop(elemtype &elem)
    {
        if (empty())
        {
            return false;
        }
        elem = st.back();
        st.pop_back();
        return true;
    }
    bool push(const elemtype &elem)
    {
        if (full())
        {
            return false;
        }
        st.push_back(elem);
        return true;
    }
    bool peek(int index, elemtype &elem) { return false; }
    int top() const { return st.size(); }
    int size() const { return st.size(); }
    bool empty() const { return 0 == st.size(); }
    bool full() const { return st.size() >= st.max_size(); }
    void print(ostream &os) const
    {
        for (vector<elemtype>::const_reverse_iterator it = st.rbegin(); it != st.rend(); ++it)
        {
            cout << *it << ' ';
        }
        return;
    }
};

class Peekback_Stack : public Stack
{
private:
    vector<elemtype> st;

public:
    Peekback_Stack(int capacity = 0) { st.reserve(capacity); }
    virtual ~Peekback_Stack() {}
    bool pop(elemtype &elem)
    {
        if (empty())
        {
            return false;
        }
        elem = st.back();
        st.pop_back();
        return true;
    }
    bool push(const elemtype &elem)
    {
        if (full())
        {
            return false;
        }
        st.push_back(elem);
        return true;
    }
    bool peek(int index, elemtype &elem);
    int top() const { return st.size(); }
    int size() const { return st.size(); }
    bool empty() const { return 0 == st.size(); }
    bool full() const { return st.size() >= st.max_size(); }
    void print(ostream &os) const
    {
        for (vector<elemtype>::const_reverse_iterator it = st.rbegin(); it != st.rend(); ++it)
        {
            cout << *it << ' ';
        }
        return;
    }
};

bool Peekback_Stack::peek(int index, elemtype &elem)
{
    if (empty() || index < 0 || index >= st.size())
    {
        return false;
    }
    elem = st[index];
    return true;
}

void test(Stack &st, int index)
{
    string s;
    if (st.peek(index, s))
    {
        cout << "peek: " << s;
    }
    else
    {
        cout << "peek failed!";
    }
    cout << endl;
    return;
}

int main()
{
    string str;
    LIFO_Stack st;

    cout << "Please enter a series of strings." << endl;
    while (cin >> str && !st.full())
    {
        st.push(str);
    }
    cout << "About to call peek() with LIFO_Stack" << endl;
    test(st, st.top() - 1);
    cout << st << endl;

    Peekback_Stack pst;
    while (!st.empty())
    {
        string t;
        if (st.pop(t))
        {
            pst.push(t);
        }
    }
    cout << "\nAbout to call peek() with Peekback_Stack" << endl;
    test(pst, pst.top() - 1);
    cout << pst;
    //测试样例:once upon a time

    return 0;
}

//-----------------------------------------------------

//Practise5.2.cpp

#include <iostream>
#include <vector>
#include <string>
using namespace std;

typedef string elemtype;
//使之前的LIFO_Stack类变为具象基类来负责之前Stack类的任务;
class Stack
{
protected:
    vector<elemtype> st;

public:
    Stack(int capacity = 0) { st.reserve(capacity); }
    virtual ~Stack() {}
    bool pop(elemtype &elem)
    {
        if (empty())
        {
            return false;
        }
        elem = st.back();
        st.pop_back();
        return true;
    }
    bool push(const elemtype &elem)
    {
        if (full())
        {
            return false;
        }
        st.push_back(elem);
        return true;
    }
    virtual bool peek(int index, elemtype &elem) { return false; }
    int top() const { return st.size(); }
    int size() const { return st.size(); }
    bool empty() const { return 0 == st.size(); }
    bool full() const { return st.size() >= st.max_size(); }
    void print(ostream &os = cout) const
    {
        for (vector<elemtype>::const_reverse_iterator it = st.rbegin(); it != st.rend(); ++it)
        {
            cout << *it << ' ';
        }
        return;
    }
};

ostream &operator<<(ostream &os, const Stack &rhs)
{
    rhs.print();
    return os;
}

class Peekback_Stack : public Stack
{
private:
    vector<elemtype> st;

public:
    Peekback_Stack(int capacity = 0) : Stack(capacity) {}
    virtual ~Peekback_Stack() {}
    virtual bool peek(int index, elemtype &elem);
};

bool Peekback_Stack::peek(int index, elemtype &elem)
{
    if (empty() || index < 0 || index >= st.size())
    {
        return false;
    }
    elem = st[index];
    return true;
}

void test(Stack &st, int index)
{
    string s;
    if (st.peek(index, s))
    {
        cout << "peek: " << s;
    }
    else
    {
        cout << "peek failed!";
    }
    cout << endl;
    return;
}

int main()
{
    Stack st;
    string str;
    Peekback_Stack pst;

    cout << "Please enter a series of strings." << endl;
    while (cin >> str && !st.full())
    {
        st.push(str);
    }
    cout << "About to call peek() with Stack" << endl;
    test(st, st.top() - 1);
    cout << st << endl;
    while (!st.empty())
    {
        string t;
        if (st.pop(t))
        {
            pst.push(t);
        }
    }
    cout << "\nAbout to call peek() with Peekback_Stack" << endl;
    test(pst, pst.top() - 1);
    cout << pst;
    //测试样例:once upon a time

    return 0;
}

//-----------------------------------------------------

//--------------------------------------------2021年7月25日 ----------------------------------------------------

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 11:53:50  更:2021-07-26 11:55:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/25 13:23:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码