• effective C ++ 学习笔记之 item 43 学习处理模板基类内的名称


    1   当我们以面向对象的观点进入template C ++ 时,继承就表现的和以前不同了

    C ++ 编译器不进入template base class 观察,解决方式有3种:

    this-> 

    using 声明式

    明确的支出被调用的函数是属于base类的

    item 43 的例子

    #include <iostream>

    using namespace std;
    class companyA
    {
    public:
    void sendCleartext(const string &msg);
    void sendEncrypted(const string &msg);
    };

    void companyA::sendCleartext(const string &msg)
    {
    cout
    << "conpanyA send clear text:" + msg << endl;
    }
    void companyA::sendEncrypted(const string &msg)
    {
    cout
    << "companyA send encrypted text:" + msg << endl;
    }

    class companyB
    {
    public:
    void sendCleartext(const string &msg);
    void sendEncrypted(const string &msg);
    };
    void companyB::sendCleartext(const string &msg)
    {
    cout
    << "companyB send clear text:" << endl;
    }
    void companyB::sendEncrypted(const string &msg)
    {
    cout
    << "companyB sned encryted text:" + msg;
    }
    class MsgInfo
    {
    public:
    MsgInfo(
    string msg)
    {
    this->msg = msg;
    }
    string getMsg();
    private:
    string msg;
    };
    string MsgInfo::getMsg()
    {
    return msg;
    }

    template
    <typename company>
    class MsgSender
    {
    public:
    //构造函数,析构函数
    MsgSender(company c)
    {

    }
    MsgSender()
    {

    }
    ~MsgSender()
    {

    }
    virtual void sendClear( MsgInfo &info)
    {
    string msg;
    msg
    = info.getMsg();
    company c;
    c.sendCleartext(msg);

    }
    virtual void sendEncrypted( MsgInfo & info)
    {
    string msg;
    msg
    = info.getMsg();
    company c;
    c.sendEncrypted(msg);
    }
    };

    template
    <typename company>
    class LoggingMsgSender:public MsgSender<company>
    {
    public:
    LoggingMsgSender(company c)
    {


    }
    ~LoggingMsgSender()
    {

    }
    void logBef(string msg)
    {
    cout
    << "log before send clear msg:" + msg << endl;
    }
    void logAfter(string msg)
    {
    cout
    << "log after send clear msg:" << msg << endl;
    }
    virtual void snedClearMsg( MsgInfo &info)
    {
    logBef(info.getMsg());
    this->sendClear(info);
    logAfter(info.getMsg());
    }

    };
    int main()
    {
    companyA companya;
    companya.sendCleartext(
    "hello world");
    companya.sendEncrypted(
    "hello world");
    companyB companyb;
    companyb.sendCleartext(
    "hello world");
    companyb.sendEncrypted(
    "hello world");
    cout
    << endl;
    cout
    << "------------------------------" << endl;
    MsgSender
    <companyA> msgsend(companya);
    MsgInfo msginfo(
    "msg");
    msgsend.sendClear(msginfo);
    cout
    << "------------------------------" << endl;
    LoggingMsgSender
    <companyA> logmsgsend(companya);
    logmsgsend.snedClearMsg(msginfo);
    cout
    << "------------------------------" << endl;
    return 0;
    }

      期间遇到的问题有:

    1. 模板类继承过程中的构造函数,默认调用的是空构造函数

    #include <iostream>

    using namespace std;
    template
    <class T>
    class base
    {
    public:
    T getx()
    {
    return x;
    }
    base(T px):x(px){}
    private:
    T x;
    };

    class drived : public base<int>
    {
    public:
    drived(
    int x):base<int>(x)
    {

    }
    };
    int main()
    {
    drived d(
    4);
    int x = d.getx();
    cout
    << x << endl;
    return 0;
    }

      2. C ++ 编译器不支持模板的分离式编译

    http://blog.csdn.net/bichenggui/article/details/4207084

    为什么boost的实现文件的后缀名是hpp了。

    当我们声明和定义一个模板的时候,必须要让声明和定义放在一个文件里。否则编译器会报错。

      3  编译出错

    template <typename Object>
    class Vector
    {
    public:
    Vector(
    int initSize = 0);
    Vector
    <Object>& operator=(const Vector &rhs);
    Object
    & operator[](int index);
    void resize(int newSize);
    void reserve(int newCapacity);
    int size() const;
    int capacity() const;
    bool empty() const;
    void push_back(const Object &x);
    void pop_back();
    const Object& pop();

    typedef Object
    *iterator;
    typedef
    const Object *const_iterator;

    iterator begin();
    const_iterator begin()
    const;

    iterator end();
    const_iterator end()
    const;

    enum { SPACE_CAPACITY = 16 };

    private:
    int theSize;
    int theCapacity;
    Object
    *objects;
    };

    #endif


    cpp中:
    template
    <typename Object>
    Vector
    <Object>::iterator Vector<Object>::begin()
    {
    return &objects[0];
    }

    template
    <typename Object>
    Vector
    <Object>::const_iterator Vector<Object>::begin() const
    {
    return &objects[0];
    }

    template
    <typename Object>
    Vector
    <Object>::iterator Vector<Object>::end()
    {
    return &objects[size()];
    }

    template
    <typename Object>
    Vector
    <Object>::const_iterator Vector<Object>::end() const
    {
    return &objects[size()];
    }


    编译错误:
    Vector.cpp:
    108: error: expected constructor, destructor, or type conversion before ‘Vector’
    Vector.cpp:
    114: error: expected constructor, destructor, or type conversion before ‘Vector’
    Vector.cpp:
    120: error: expected constructor, destructor, or type conversion before ‘Vector’
    Vector.cpp:
    126: error: expected constructor, destructor, or type conversion before ‘Vector’

      如果没有typename,编译器会认为const_iterator是Vector<Object>的静态数据成员!编译报错,解决方法是:

    template <typename Object>

    typename Vector<Object>::const_iterator Vector<Object>::begin() const

    {

    return &objects[0];

    }

    #include <iostream>

    template
    <typename Object>
    class Vector
    {
    public:
    Vector(
    int initSize = 0);
    Vector
    <Object>& operator=(const Vector &rhs);
    Object
    & operator[](int index);
    void resize(int newSize);
    void reserve(int newCapacity);
    int size() const;
    int capacity() const;
    bool empty() const;
    void push_back(const Object &x);
    void pop_back();
    const Object& pop();

    typedef Object
    *iterator;
    typedef
    const Object *const_iterator;

    iterator begin();
    const_iterator begin()
    const;

    iterator end();
    const_iterator end()
    const;

    enum { SPACE_CAPACITY = 16 };

    private:
    int theSize;
    int theCapacity;
    Object
    *objects;
    };





    template
    <typename Object>
    typename Vector
    <Object>::iterator Vector<Object>::begin()
    {
    return &objects[0];
    }

    template
    <typename Object>
    typename Vector
    <Object>::const_iterator Vector<Object>::begin() const
    {
    return &objects[0];
    }

    template
    <typename Object>
    typename Vector
    <Object>::iterator Vector<Object>::end()
    {
    return &objects[size()];
    }

    template
    <typename Object>
    typename Vector
    <Object>::const_iterator Vector<Object>::end() const
    {
    return &objects[size()];
    }


    int main()
    {

    return 0;
    }

      


  • 相关阅读:
    30.过滤掉smb.conf配置文件中的空行和注释行和空白行(初级写法很不严谨)
    29. 分析文件内容,判断 fgets 共执行了多少次?
    28. 使用fgetc()/fputc()实现文件的加密与解密,存在溢出风险。
    27.读文件时通过两种方式判断文件结尾
    26. 使用fgetc()/fputc()实现文件的拷贝
    24. 练习定义几种指针及数组
    23. 实现 func()函数,在func()中,通过操作arr,实现修改str1到str2字符串,并打印所有字符串,考察对指针与数组与字符串的基本掌握
    Windows程序设计(Charles Petzold)HELLOWIN程序实现
    jvm 解释器和JIT编译器
    java 创建线程的方法
  • 原文地址:https://www.cnblogs.com/hitwtx/p/2156002.html
Copyright © 2020-2023  润新知