这是我的代码:
class SimpleProduct {
char look = 'x';
string name = "Undefined";
string type = "Undefined";
string description = "Undefined";
public:
char getLook() const {return look;}
string getType() const {return type;}
string getName() const {return name;}
string getDescription() const {return description;}
SimpleProduct(char look = 'x', string &&name = "Undefined", string &&type = "Undefined", string &&description = "Undefined");
string toString() const;
};
class TallProduct : public SimpleProduct {
public:
TallProduct(char look, string &&name = "Undefined", string &&type = "Undefined", string &&description = "Undefined");
string toString() const;
};
inline SimpleProduct::SimpleProduct(char look, string &&name, string &&type, string &&description) :
look(look), name(move(name)), type(move(type)), description(move(description)) {
}
inline string SimpleProduct::toString() const {
ostringstream ost;
if (this->getName() == "Space") {
ost << "";
} else {
ost << "Look: " << this->getLook() << ", name: " << this->getName() << ", type: " << this->getType() << ", description: "
<< this->getDescription();
}
return ost.str();
};
inline TallProduct::TallProduct(char look, string &&name, string &&type, string &&description){
}
inline string TallProduct::toString() const {
return "TALL | " + SimpleProduct::toString();
}
这是我的考验:
TEST(Test3, TallProduct) {
SimpleProduct *product = new TallProduct('t', "Fresh sandwich", "sandwich", "check the expiration date");
ASSERT_EQ("TALL | Look: t, name: Fresh sandwich, type: sandwich, description: check the expiration date", product->toString());
}
我得到的结果总是这样:
"Look: x, name: Undefined, type: Undefined, description: Undefined"
应为:
"TALL | Look: t, name: Fresh sandwich, type: sandwich, description: check the expiration date"
您可以指示我在哪里犯了错误?我猜错误的地方在调用方法::tostring
周围,但不知道如何调用TallProduct::toString
而不是SimpleProduct::toString
。
答案 0 :(得分:1)
您的TallProduct
构造函数未初始化其基类。写
inline TallProduct::TallProduct(char look, string &&name, string &&type, string &&description) :
SimpleProduct::SimpleProduct(look, std::move(name), std::move(type), std::move(description))
{
}
还有,您的基类的功能不是virtual。这意味着对product->toString()
的调用将始终调用SimpleProduct::toString
,因为product
的类型为SimpleProduct *
,即使所指向的对象的类型为TallProduct
。如果将函数声明为virtual
,则程序将在运行时查找要调用的内容。
还必须声明虚拟基类的析构函数。在上面的链接中阅读有关内容。否则,您将调用未定义的行为。
答案 1 :(得分:1)
问题的另一半是:由于TallProduct
没有初始化SimpleProduct
,SimpleProduct
中的所有类变量都具有默认值。
char look = 'x';
string name = "Undefined";
string type = "Undefined";
string description = "Undefined";
因此ASSERT_EQ
宏的参数不相等
答案 2 :(得分:1)
这是多态性的典型情况。您的*product
指针变量为SimpleProduct
类型,但是您已为其分配了一个TallProduct
对象,并假定调用product->toString()
将调用{{1 }}。事实并非如此。
这称为编译时/静态绑定。这意味着在编译期间,您的编译器会将TallProduct
调用绑定到toString()
的{{1}}版本,因为这是正确的逻辑决定吗?
但是,如果您在product->toString()
和SimpleProduct
中将toString()
方法定义为toString()
,则编译器会说:“好的,我不会将任何方法绑定到此调用权限现在,我们将在运行时看到根据virtual
引用的变量的实际类型实际调用哪个方法。”
详细了解C++ Polymorphism。
详细了解静态和动态绑定Virtual functions (C++ only)