C++中的l-value substr方法

Min*_*wer 2 c++ substring substr lvalue

我想在我创建的substr字符串类中用C++ 创建一个方法.

字符串类当然是基于C风格的字符串,我负责内存管理.

我想编写一个substr(start, length)可以常规方式工作的函数:

CustomString mystring = "Hello";

cout << mystring.substr(0,2); // will print "He"
Run Code Online (Sandbox Code Playgroud)

并且也是这样:

mystring.substr(1,3) = "DD"; // mystring will be "HDDo"
Run Code Online (Sandbox Code Playgroud)

请注意,即使我得到一个3个字符长的子字符串,我只将2个字符放入赋值,输出字符串仍然是HDDo.

知道怎么做到这一点?

谢谢!

Jer*_*fin 6

为了支持这一点,您可能必须编写您的代码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
Run Code Online (Sandbox Code Playgroud)

编辑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);
}
Run Code Online (Sandbox Code Playgroud)