1. Foreword
previous article own realization of a simple string class is mentioned in the realization of the + operator overloaded functions, in order to prevent the return generated temporary object to call the copy constructor dynamic application memory space, using a function called the move , it is the C + +0 x of the new features. Since it is a new C + +0 x features, it does not have this feature in the previous case, for the temporary object dynamic memory space problem is not there can be other ways to solve or avoid it? The answer is yes, you can use Expression Template (expression templates, ET) to resolve.
2. expression template
For the previous String class, we may often use the following expression:
String str4 = str1 + str2 + str3;
this expression there is a problem, is to produce a "unnecessary" temporary object. Because str1 + str2 results will be stored in a temporary object temp1, and then temp1 + str3 results will be stored in order on a temporary object temp2, temp2 finally the results to str4 initialized. If these vectors is very long, or expression plus sections, will not only have a lot of temporary objects, but also to dynamically allocate memory space to store the String internal string, which is obviously inefficient. move function to solve when the + operator overloading function returns a temporary object, the compiler copies the stack for another object overhead (because the + operator overloading function temp1 temporary objects declared within the scope of foreign affairs in the function can not be used, so The compiler automatically calls the + operator in the region overloaded function declares a temporary object temp11, used to store copies of temp1), but does not solve the problem of generating temporary objects. Expression template idea is very simple, it is calculated on the + operation is postponed, that is a one-time calculation of all the + operator, so that you do not need to generate a temporary object to hold the + operator's provisional results. Due to the postponement calculations, so you must save str1, str2, str3 operands used in the subsequent calculation of deferred real + operator.
3. Based String expression templates
Although expression template idea is very simple, but its implementation is not so easy indeed. The original practices, operator + were calculated directly, since we do not want it "premature" computing, then we must re-overloading an operator + operator, this operation is not performed in real arithmetic, just generate an object In this object on both sides of the addition operator operand preserved, and then allow it to participate to go to the next step in the calculation. (Okay, this object is temporary, but its price is very very small, because it does not require dynamic application memory space, we first ignore it).
class String;
template <typename L>
class ExpPlus {
const L &lstr;
const char *rstr;
const int _size;
public:
ExpPlus(const L & a_l, const char *a_r):lstr(a_l), rstr(a_r), _size(strlen(a_r))
{
}
ExpPlus(const L & a_l, const char &a_r):lstr(a_l), rstr(&a_r), _size(1)
{
}
ExpPlus(const L & a_l, const String &a_r):lstr(a_l), rstr(a_r.c_str()), _size(a_r.size())
{
}
void copy_str(char *d_str) const;
int size() const
{
return _size + lstr.size();
}
};
template <typename L>
void ExpPlus<L>::copy_str(char *d_str) const
{
lstr.copy_str(d_str);
strncpy(d_str + lstr.size(), rstr, _size);
}
//用于+模板
template <typename L>
ExpPlus<L> operator + (const L & a_l, const char & a_r) {
return ExpPlus<L>(a_l, a_r);
}
template <typename L>
ExpPlus<L> operator + (const L & a_l, const char* a_r) {
return ExpPlus<L>(a_l, a_r);
}
template <typename L>
ExpPlus<L> operator + (const L & a_l, const String & a_r) {
return ExpPlus<L>(a_l, a_r);
}
We've added a template class ExpPlus, use it to calculate the representative of the addition of the "expression", but during the addition, it does not itself carry out the calculation of the real . For this class, defines copy_str function, this function was performed in a real string addition calculation. Of course, in addition to support the preservation of the String object, but also support the preservation char and char *. Because String objects plus string constants and character is also very common, such as the following expression:
String str2 = str1 + 'a' + "cd"
for us to achieve the String class, you must override an operator = function again, for one-time calculation of the value of the expression on the right. Modified String code is as follows:
class String
{
public:
。。。
template <typename Exp>
String& operator=(const Exp &a_r); //新加
。。。
void copy_str(char *d_str) const; //新加
};
void String::copy_str(char *d_str) const
{
strcpy(d_str, _string);
}
template <typename Exp>
String& String::operator=(const Exp &a_r)
{
char *temp_str;
int size = a_r.size();
temp_str = new char[size + 1];
a_r.copy_str(temp_str);
temp_str[size] = 0;
if (_string)
delete _string;
_string = temp_str;
_size = size;
return *this;
}
above gives only the newly added code, other code in the own realization of a simple string class has been given.
above passage, for people who do not understand the ET, maybe one time is not easy to understand, we go step by step:
in str4 = str1 + str2 + str3 this formula, the first encounter str1 + str2, time, operator + template function will be called, then just generate a temporary ExpPlus
Finally, when the time for str4 = t2, String assignment operator is invoked (with t2 as a parameter). Note that this call statement a_r.copy_str (temp_str), is actually calling the t2.copy_str (temp_str), t2.copy_str function in turn calls t1.copy_str, t1 and call str1.copy_str, so step by step would str1 , str2, str3 the string copied to temp_str, and ultimately get str4 = str1 + str2 + str3. Like change "magic" as we passed ExpPlus completed the "delay calculation," and to avoid a large-scale temporary String object generation.
4. Summary
expression template maintained expression of both intuitive and efficient, very powerful, but it is clear that it is too complicated, mainly as a class library designers weapons. In addition, it may also enable the user to understand some of the "new" things, like, if I want to store the value of the expression in the middle, then
Reference: http: / / www.cnblogs.com/liyiwen/archive/2009/12/03/1616627.html
http:// www.cppblog.com/kesalin/archive/2009/05/28/85983.html
没有评论:
发表评论