我正在编写“开始使用C ++早期对象”第7版中的一个编程挑战,其中一个分配要求创建一个派生自STL字符串类的类。我发布的问题是为了理解我被允许做什么,以及我应该如何实施解决方案,以便没有人提供更高级的建议。
- 问题,因为它写在文本中 -
回文测试
Palindrome是一个向前读取相同内容的字符串。例如,妈妈,爸爸,女士和雷达这些词都是回文。写一个class Pstring
来自STL string class
。 Pstring 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.
}
}
我觉得我这样做不正确的原因是因为赋值使用下标表示法,但是,如果我不知道字符串所在的变量的名称,我不明白如何使用下标表示法存储
任何帮助都将不胜感激,因为作者不提供解决方案,除非我是一名在我看来非常蹩脚的教练。这可能与这是学术文本这一事实有关。
答案 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;
}
};