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;
}
一个不会敲代码的程序员