Добавление функции в строковый класс - PullRequest
3 голосов
/ 04 августа 2011

Я понимаю, что наследование от std :: string class - плохая идея, но я просто пытался добавить пользовательскую функцию в строковый класс для фиктивного присвоения, используя наследование.Я хочу вызывать свою функцию как add и когда я делаю str.add (str1, str2);он должен добавить str1 в начале строки и str2 в конце строки.Этот класс (унаследованный строковый класс) является закрытым классом-членом другого класса (скажем, Parent).когда я пытаюсь получить доступ к моему объекту класса string с помощью этого, он указывает на класс Parent.Как я могу это сделать?

Спасибо

Ответы [ 3 ]

3 голосов
/ 04 августа 2011

Я не уверен, что понимаю все аспекты вашего вопроса.Когда вы говорите, закрытый член класса, вы имеете в виду частную переменную члена?Или это частное наследство?Я не понимаю, «когда я пытаюсь получить доступ к моему объекту класса string с помощью этого, он указывает на родительский класс».

Вы правы, наследование от std :: string, вероятно, не очень хорошая идея,Прежде всего, для того, чтобы сделать его членом производной строки, вы должны знать достаточно много о базовой реализации;это может измениться от распределения к распределению, делая код непереносимым.Если вы напишите реализацию, которая является переносимой, используя уже определенный интерфейс, предоставляемый std :: string, вы все равно не сможете воспользоваться какой-либо реальной оптимизацией.Если у вас нет действительно веской причины для этого, вам лучше вообще этого не делать.

Во-вторых, название «добавить», вероятно, не самое лучшее, так как оно не описывает то, что выделаешь."Surround" может быть лучшим именем.

Я думаю, что внешняя функция, как это может быть лучше, избегая всей идеи наследования от строки:

void surround(std::string &orig, std::string const &pre, std::string const &post) {
    orig = pre + orig + post;
}

или, если вы хотите более высокуюпроизводительность, сделайте что-то вроде этого:

void surround(std::string &orig, std::string const &pre, std::string const &post) {
    std::string str;
    str.reserve(orig.size() + pre.size() + post.size());
    str.insert(str.end(), pre.begin(), pre.end());
    str.insert(str.end(), orig.begin(), orig.end());
    str.insert(str.end(), post.begin(), post.end());
    std::swap(str, orig);
}
2 голосов
/ 04 августа 2011

Не наследуйте от std::string, это действительно плохая идея. Вам придется писать правильные конструкторы и никогда не использовать их с полиморфизмом, потому что std::string не имеет виртуального деструктора. Просто напишите бесплатную функцию.

0 голосов
/ 04 августа 2011

Обязательно объявите свою функцию в открытом разделе класса.

Может быть, вы бы предпочли композицию, а не наследство;)

    class MyString
    {
           std::string m_string; // do not inherit just composition it
    public:
            explicit MyString(const std::string& str)
                   : m_string(str)
            {
            }

            // your function should be in public scope I think
            MyString& add(const std::string& begin, const std::string& end)
            {
                    m_string.insert(0, begin);
                    m_string.append(end);
                    return *this;
            }

            const std::string& string() const
            {
                    return m_string;
            }
    };

    class Parent
    {
            MyString m_string;
    public:
            void surround(const std::string& begin, const std::string& end)
            {
                    m_string.add(begin, end);
            }
    };

    int main(int argc, char *argv[])
    {
            std::cout << MyString("inherit").add("Do not ", " from std::string!").string() << std::endl;
            return 0;
    }
...