此C ++代码的继承有什么问题

时间:2019-11-30 13:02:02

标签: c++

这是我的代码:

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

3 个答案:

答案 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))
{
}

请参见delegating constructors

还有,您的基类的功能不是virtual。这意味着对product->toString()的调用将始终调用SimpleProduct::toString,因为product的类型为SimpleProduct *,即使所指向的对象的类型为TallProduct。如果将函数声明为virtual,则程序将在运行时查找要调用的内容。

必须声明虚拟基类的析构函数。在上面的链接中阅读有关内容。否则,您将调用未定义的行为。

答案 1 :(得分:1)

问题的另一半是:由于TallProduct没有初始化SimpleProductSimpleProduct中的所有类变量都具有默认值。

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)