我试图从我的二级课程中找出这个作业。 我们要创建一个名为Number的类,派生自std :: string。 这个类中唯一的代码是两个构造函数,一个默认值和一个将字符串作为争论的构造函数。 我有:
class Number : public string {
public:
Number();
Number(string set);
}
然后将构造函数编码为:
Number::Number() : string("0") { } // default constructor sets data string to "0"
Number::Number(string set) : string(set) { }
到目前为止一切顺利。然后我们将采用我们一直在开发的两个类,Double和Integer,并从Number派生它们。在这两个类中,我们曾经分别使用double和int作为数据成员。现在,由于继承,我们应该有一个内置的数据部分(字符串)。我遇到的问题是我的所有operator =()重载现在都在所有路径上递归#34;在运行时导致stackoverflow。我将展示一个带有字符串的Double构造函数的示例,以及导致无限递归的equals函数。
Double::Double(string d) : Number(d)
{
// overloaded constructor that takes a string argument
if (isNaN(d)) {
*this = "0.0";
}
else {
*this = d;
}
// used for setting the value of a data member with a string
void Double::operator=(string d)
{
if (isNaN(d)) {
*this = "0.0";
}
else {
*this = d;
}
}
}
我看到递归发生在哪里*这是调用overloaded =调用自己,因为我在=函数本身使用* this。那么将数据成员设置为提供的值的正确语法是什么呢?在它之前 - > dataMemberName =正确类型的提供值。
应该注意,我的非字符串构造函数确实设置了实例化对象的值:
Double::Double(int d) : Number(to_string(d)){}
但是第二次我尝试用它们做任何事情,+ - * /,调用=函数然后再次发生错误。
答案 0 :(得分:2)
只需添加:
using std::string::operator=;
缩写示例:
#include <string>
class Number : public std::string {
public:
};
class Double : public Number {
public:
using std::string::operator=;
Double()
{
*this="0.0";
}
};
答案 1 :(得分:1)
在评论中讨论后,我决定重写我的答案,以便更清楚我的意思。
您应该只调用基类operator=
并让它处理成员分配。
您的class Number
定义如下:
class Number : public string {
public:
Number();
Number(string set);
};
这个课程可以为我们工作,因为我们想要它没有任何修改?我们来看看。
我们需要的第一件事是基类中的
operator=
。
operator=
既没有声明,也没有delete
在类Number
中,这意味着如果你调用Number& Number::operator=(Number const&)
,编译器会为你生成这个函数。所以我们在这里很好。
对我的解决方案而言重要的第二件事是从
std::string
转换为Number
。
班级Number::Number(std::string)
中有构造函数Number
。幸运的是,它没有被声明为explicit
,它可以隐式使用(使用explicit
构造函数,它会更详细,但也可能)。当需要将std::string
转换为Number
时,编译器将使用此构造函数。单参数构造函数有时称为转换构造函数。
好的,我们已经满足了第二个要求。
这就是基类需要的全部内容!
现在上班。
我们从创建辅助函数开始:
std::string check_for_NaN(std::string s)
{
if(isNaN(s)) { return "0.0"; }
return s;
}
现在我们可以简化Double
的构造函数:
Double::Double(std::string s): Number(check_for_NaN(s)) //no magic here
{}
我们可以为课程operator=
创建期待已久的Double
:
Double& operator=(std::string rhs)
{
Number::operator=(check_for_NaN(rhs)); //here we have magic, explained below
//if Double has some members of its own, copy them here
return *this;
}
那么,当我们调用'Number :: operator =(check_for_NaN(rhs));'时会发生什么?
check_for_NaN(rhs)
返回正确的字符串对象。Number::operator=(std::string)
但找不到它。Number::operator=(const Number&)
!std::string
转换为Number
。Number::Number(std::string)
构造函数不明确!std::string rhs
开始,它会创建一个类Number
的临时对象。答案 2 :(得分:1)
您可以直接指定要使用size
的{{1}}:
std::string