【问题标题】:C++ type casting error setting and getting derived class members in/from an array (**)C++ 类型转换错误设置和从数组中获取派生类成员 (**)
【发布时间】:2016-03-28 11:59:13
【问题描述】:

您好,我在使用 Computer.cpp 中的 set 和 get 方法时遇到问题。我不断收到类型转换错误,例如

从表达式中引用类型“const Case&”的初始化无效 'Case' 或 'Part'、'Part*' 等类型的。

我想要做的是将不同的计算机部件(“部件”是各种具体部件的超类,如机箱、显示器、cpu 等)存储到数组中

Part** m_requiredParts; 

这是代码摘录,我在 qt creator 3.6.0 上运行它。

头文件,

Computer.h 

#ifndef COMPUTER_H
#define COMPUTER_H

class Computer : public ComputerPlan
{
public:

    /**
     * @brief Computer default constructor
     */
    Computer();

    /**
     * @brief ~Computer destructor
     */
    virtual ~Computer();

    // Getters
    /**
     * @brief getCase retrieves the computer's case information
     * @return the computer's Case
     */
    virtual const Case& getCase() const;

    // Setters
    /**
     * @brief setCase setter method for Case
     * @param computerCase computer's Case
     */
    virtual void setCase(const Case &computerCase);

protected:

    Part** m_requiredParts;

};

#endif // COMPUTER_H

.CPP 文件

Computer.cpp

#include "Computer.h"

Computer::Computer()
{
    m_requiredParts = new Part* [8];
}

Computer::~Computer()
{

}

const Case& Computer::getCase() const
{
    const Case& c = (Case&)m_requiredParts[0];
    return c;
}

void Computer::setCase(const Case &computerCase)
{
    m_requiredParts[0] = (Part*) &computerCase;
    //Part**
}

添加一些附加信息,

我在 main.cpp 中通过以下方式设置和获取它们

Computer* computer = new Computer();
computer->setCase(Case("NZXT", Tower));
std::string expected = "Case: NZXT, Case Type: Tower";
std::string actual = std::string(computer->getCase().getPartInformation());
delete computer;
return expected == actual;

【问题讨论】:

  • 你怎么称呼setCase

标签: c++ arrays pointers casting type-conversion


【解决方案1】:

这本身不是一个答案,但它太大而不能成为评论,需要指出

computer->setCase(Case("NZXT", Tower));

创建一个临时的Case,您可以在setCase 中使用const & 捕获该Caseconst & 将临时的生命周期延长到函数中,所以我们在那里没问题。不幸的是,您在setCase 中存储了指向该临时文件的指针。当函数结束时,const & 超出范围,临时对象现在没有任何绑定,因此它也被销毁。现在你有了一个指向不再存在的对象的指针。

您需要确保您粘贴到 setCase 的对象比您放入的 Computer 的寿命更长。

【讨论】:

  • 这是否意味着我需要将对象深度复制到数组中以防止这种情况发生?
  • @lukieleetronic Welll 你的班级应该有一个适当的复制构造函数,但这不是我想要的。您需要确保创建传递给setCaseCase 对象比Computer 对象的寿命更长。否则,您将拥有一个指向不存在的对象的指针,并且尝试使用它是未定义的行为。
  • 哇,只是为了尝试一下,我已经深度复制了这个对象,它就像一个魅力!,我没有看到导致这一切的临时提前结束的范围问题,非常感谢!
【解决方案2】:

您必须从指针数组中取消引用指针:

const Case& c = (Case&)(*m_requiredParts[0]);

此外,使用 c 样式类型转换也不是好习惯,请改用 static_cast 或 dynamic_cast:

const Case& c = static_cast<Case&>(*m_requiredParts[0]);

在你的类实例中存储指向外部对象的指针是个坏主意。

关于这个computer-&gt;setCase(Case("NZXT", Tower)); 用例,在类实例中存储指向临时的指针绝对是个坏主意,使用new 并更改原型以接受指针。并且不要忘记在析构函数中进行清理。

【讨论】:

  • 谢谢,我忘了尊重我的 m_requiredParts!
猜你喜欢
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 2010-11-01
  • 1970-01-01
  • 2019-10-11
相关资源
最近更新 更多