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

How do I access the member variables in the STL string class?

本文关键字:成员 变量 字符串 STL 何访问 访问      更新时间:2023-10-16

我正在处理《从c++早期对象开始》第7版中的一个编程挑战,其中一个作业要求创建一个从STL字符串类派生的类。我发布这个问题的目的是了解我被允许做什么,以及我应该如何实现解决方案,这样就没有人提供更高级的建议。

——按原文提问——

回文测试

Palindrome是一个向后读和正向读相同的字符串。例如,单词mom, dadmadamradar都是回文。写出由STL string class导出的class PstringPstring class增加成员函数

bool isPalindrome()

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

您可能会发现使用string类的下标操作符[]很有用:如果str是字符串对象,k是整数,则str[k]返回字符串中k位置的字符。

——结束——

我的主要问题是我如何访问持有我的字符串对象的成员变量,如果我从类派生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.
  }
}

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

任何帮助都将非常感激,因为作者不提供解决方案,除非我是一个在我看来相当蹩脚的讲师。这可能与这是一篇学术文章有关。

您不应该继承std::string,因为它不是为此而设计的,您也不需要这样做来查找回文。

参见:继承和重写std::string的函数?

回文解决方案(从这个问题:检查字符串是否为回文链接从这:c++回文查找器优化)

#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
    }
};

这本书没有涉及auto,因为这个关键字是最近才添加到语言中的。如果你的编译器已经有一年多的历史了,或者不是一个大的名字,它可能不支持它。

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

当然,父类的成员函数可以像子类的成员函数一样被访问——你只需要调用它们。

成员操作符重载有点棘手,但仍然不算太糟。您需要提供用来调用它们的实例,即*this。你也可以用operator关键字来调用它们,但在我看来,这有点笨拙。

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

如果您不想使用auto,那么您可以简单地使用std::string::iterator代替,这就是auto在这种情况下无论如何都要解决的问题。

因此问题#1得到满足。


当你调用begin()end()时,你调用的是超类std::string中的成员begin()end()

因此问题#2得到满足。

试试这个:

#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;
    }
};