如何访问STL字符串类中的成员变量?

时间:2011-12-24 04:35:52

标签: c++ string class

我正在编写“开始使用C ++早期对象”第7版中的一个编程挑战,其中一个分配要求创建一个派生自STL字符串类的类。我发布的问题是为了理解我被允许做什么,以及我应该如何实施解决方案,以便没有人提供更高级的建议。

- 问题,因为它写在文本中 -

回文测试

Palindrome是一个向前读取相同内容的字符串。例如,妈妈,爸爸女士雷达这些词都是回文。写一个class Pstring来自STL string classPstring class添加了成员​​函数

bool isPalindrome()

确定字符串是否为回文结构。包含一个构造函数,该构造函数将STL string对象作为参数并将其传递给字符串基类构造函数。通过主要程序测试您的类,该程序要求用户输入字符串。程序使用字符串初始化Pstring对象,然后调用isPalindrome()来确定输入的字符串是否是回文。

你可能会发现使用字符串类的下标operator []很有用:如果str是一个字符串对象而k是一个整数,那么str [k]返回字符串中位置k的caracter。

- 结束 -

我的主要问题是,如果我从Pstring派生的类是一个我没写过的类而且我不知道它是如何实现其成员的,那么如何访问保存我的字符串对象的成员变量?

例如,

#include <string>
using namespace std;

class Pstring : public string
{
public:
  Pstring(std::string text)
   : string(text) { }

  bool isPalindrome()
  {
    // How do I access the string if I am passing it to the base class?

    // What I think I should do is...
    bool is_palindrome = true;
    auto iBegin = begin();
    auto iEnd   = end() - 1;

    while (iBegin < iEnd && is_palindrome)
    {
      if (*iBegin++ != *iEnd--)
        is_palindrome = false;
    }

    return is_palindrome;

    // But I think this is wrong because...
    // #1 The book did not discuss the keyword auto yet
    // #2 The book discussed when a class is derived from another class,
    //    how the members from super class will be accessible to the sub class.
    //    However, with this assignment, I don't see how to access the members.
  }
}

我觉得我这样做不正确的原因是因为赋值使用下标表示法,但是,如果我不知道字符串所在的变量的名称,我不明白如何使用下标表示法存储

任何帮助都将不胜感激,因为作者不提供解决方案,除非我是一名在我看来非常蹩脚的教练。这可能与这是学术文本这一事实有关。

4 个答案:

答案 0 :(得分:3)

你不应该继承std :: string,因为它不是为此而设计的,你也不需要为了找到回文。

请参阅:Inheriting and overriding functions of a std::string?

回文解决方案(来自此问题:Check if a string is palindrome与此相关联:C++ Palindrome finder optimization

#include <algorithm>

bool isPal(const string& testing) {
    return std::equal(testing.begin(), testing.begin() + testing.size() / 2, testing.rbegin());
}

这本书的质量似乎值得怀疑。免费函数(取决于你问的对象)几乎总是比成员函数更受欢迎,特别优于继承。


如果必须使用继承:

class Pstring : public string
{
    //...

    bool isPalindrome()
    {
      return std::equal(begin(), begin() + size() / 2, rbegin());

      // as a side-note, 'iterator' will refer to the inherited return type of begin()
      // Also, 'operator[](x)' will call the subscript operator
    }
};

答案 1 :(得分:1)

这本书没有涵盖auto,因为该关键字最近才添加到该语言中。如果你的编译器已经超过一年,或者不是其中一个大名字,那么它可能不支持它。

对于此问题,您无需访问任何成员变量以获得正确的解决方案,因此无需担心它们是什么或是否可以访问它们。好的,因为标准没有指定 - 这是你的特定编译器定义的所有实现细节,如果你发现自己深入挖掘,你应该问问自己你做错了什么。

当然,父类的成员函数可以作为子类的成员函数访问 - 您只需要调用它们。

成员操作员重载有点棘手,但仍然不是太糟糕。您需要提供实例来调用它们,即*this。您也可以使用operator关键字来呼叫它们,但我认为这有点笨拙。

if ((*this)[i] == (*this)[j])

if (operator[](i) == operator[](j))

答案 2 :(得分:0)

如果您不想使用自动,那么您只需使用std::string::iterator代替,auto就是这种情况下正在解决的问题。

因此问题#1得到满足。


当您呼叫begin()end()时,您正在超级类std :: string中调用成员begin()end()

因此问题#2得到满足。

答案 3 :(得分:0)

试试这个:

#include <string>

class Pstring : public std::string
{
public:
    Pstring(const std::string &text)
        : std::string(text) { }

    bool isPalindrome()
    {
        std::string::size_type len = length();
        std::string::size_type half = len / 2;
        for (std::string::size_type idx = 0; idx < half; ++idx)
        {
            if ((*this)[idx] != (*this)[len-idx-1])
                return false;
        }
        return true;
    }
};