爲了支持這一點,您可能必須編寫您的substr()
以返回一個代理對象,用於跟蹤原始字符串的哪部分被引用。該代理對象將重載operator=
,並將在其中將新引用的子字符串替換爲新分配的字符串。
編輯迴應評論:代理的想法是,它是足夠類似於它是代理的類返回代理仍然是一個封閉的操作 - 即從用戶的角度來看,所有可見的是原始類型的對象,但它具有在沒有代理的情況下不可能實現的功能(或者會更難實現)。在這種情況下,我們代理類對於字符串類是私有的,所以用戶不能創建代理類的實例,除非是臨時的。如果您指定了該臨時文件,則可以使用該臨時文件來修改其父字符串。以任何其他方式使用代理只會產生一個字符串。
至於這樣做會讓你試圖在原始字符串中做所有事情:每個代理對象都是一個臨時對象 - 編譯器可以/將會跟蹤如何根據需要創建臨時對象,並正確銷燬它們在完整表達式的末尾等。編譯器還會跟蹤特定分配引用的子字符串,當我們嘗試使用它的值時會自動將其轉換爲字符串,等等。簡而言之,編譯器可以處理幾乎所有涉及的艱苦工作。
這是一些工作代碼。周圍的字符串類是非常小的(例如它沒有搜索能力)。我希望能夠爲字符串類的有用版本添加相當的數量。然而,代理類是完整的 - 我不希望在字符串類的功能完整版中看到它發生很大變化(如果有的話)。
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
class string {
std::vector<char> data;
public:
string(char const *init) {
data.clear();
data.assign(init, init+strlen(init));
}
string(string const &s, size_t pos, size_t len) {
data.assign(s.data.begin()+pos, s.data.begin()+pos+len);
}
friend class proxy;
class proxy {
string &parent;
size_t pos;
size_t length;
public:
proxy(string &s, size_t start, size_t len) : parent(s), pos(start), length(len) {}
operator string() { return string(parent, pos, length); }
proxy &operator=(string const &val) {
parent.data.erase(parent.data.begin()+pos, parent.data.begin()+pos+length);
parent.data.insert(parent.data.begin()+pos, val.data.begin(), val.data.end());
return *this;
}
};
proxy substr(size_t start, size_t len) {
return proxy(*this, start, len);
}
friend std::ostream &operator<<(std::ostream &os, string const &s) {
std::copy(s.data.begin(), s.data.end(), std::ostream_iterator<char>(os));
return os;
}
};
#ifdef TEST
int main() {
string x("Hello");
std::cout << x << std::endl;
std::cout << x.substr(2, 3) << std::endl;
x.substr(2, 3) = "DD";
std::cout << x << std::endl;
return 0;
}
#endif
編輯2: 至於子的子去,這要看情況。目前沒有涉及的一種情況是,如果您想要分配給子字符串的子字符串,並且會影響原始字符串。如果你想要像x=y.substr(1,4).substr(1,2);
這樣的東西,它會正常工作。第一個代理將被轉換爲一個字符串,第二個substr將在該字符串上被調用。
如果你想要:x.substr(1,4).substr(1,2) = "whatever"
;它目前不會工作。我不知道它實現了,但這樣的假設是這樣,除了支持是相當小的 - 你一SUBSTR成員添加到代理:
proxy substr(size_t start, size_t len) {
return proxy(parent, pos+start, len);
}
C++需要什麼。 *另一個*字符串類。 – jalf 2009-10-16 19:52:51
「......編寫字符串類是C++程序員中最受歡迎的室內運動之一。」 (P.J.Plauger,「The Draft C++ Standard Library」,p345) – sbi 2009-10-16 20:24:46
* I *在一年或兩年前寫了一個鏈表類。因爲我知道C++ *需要另一個LL類。 – 2009-10-16 20:48:31