2016-03-28 8 views
1

こんにちは私はComputer.cppのsetメソッドを取得しています。私は型キャストエラーを得ることに保つようにC++型のキャストエラーの設定と、配列からの派生クラスメンバの取得(**)

表現 から参照型「constのケース&」の

無効な初期化などのタイプ「ケース」または「パート」、「パート*」の

として私は何をしたいここで配列

Part** m_requiredParts; 

に(「パート」とは、などの場合、モニター、CPUなどの各種のコンクリート部​​品のスーパークラスである)別のコンピュータ部品を格納することです私は、コードのエキスですそれをqt creで実行するator 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は、いくつかのaddtionalの情報を追加する

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; 
+0

をoutlivesために起こっている?を確認する必要があり

NathanOliver

答えて

1

これは、それ自体が答えではないが、コメントであることが大きすぎると、それは

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

はあなたがsetCaseconst &に取り込む一時的Caseを作成します指摘する必要があります。 const &は、ファンクションにテンポラリの存続期間を延長するので、そこに問題はありません。残念ながら、その一時的なポインタをsetCaseに保存します。関数が終了すると、const &は範囲外になり、一時的には何もバインドされていないので、それも破棄されます。これで、もはや存在しないオブジェクトへのポインタができました。あなたはsetCaseにPASEあなたのオブジェクトがComputerあなたがそれを置く。あなたはsetCase` `を呼び出すにはどうすればよい

+0

これが起こらないようにオブジェクトを配列に深くコピーする必要がありますか? – lukieleetronic

+0

@lukieleetronic Welllクラスには適切なコピーコンストラクタが必要ですが、それは私が得意でないものです。 'set'オブジェクトへのパスを作成する' Case'オブジェクトが 'Computer'オブジェクトよりも長生きしていることを確認する必要があります。それ以外の場合は、存在しないオブジェクトへのポインタがあり、それを使用しようとすると未定義の動作になります。 – NathanOliver

+0

うわー、ちょうどそれを試してみると、私はオブジェクトを深くコピーして魅力的なように動作します!私はこの問題を引き起こしていた一時的な終わりの範囲を見ていませんでした。 – lukieleetronic

1

y OUは、あなたのポインタの配列からポインタを逆参照する必要があります。また

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

タイプがキャストCスタイル、使用static_castをまたは代わりにdynamic_castを使用することをお勧めではありません。

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

をそして、それはおそらく悪い考えですあなたのクラスインスタンスの中にextarnalオブジェクトへのポインタを格納する。

これについてはcomputer->setCase(Case("NZXT", Tower));ユースケースでは、クラスインスタンス内に一時的にポインタを格納することは間違いですが、newを使用してポインタを受け入れるようにプロトタイプを変更してください。デストラクタのクリーンアップを忘れないでください。

+0

ありがとう、私は私のm_requiredPartsを尊敬するのを忘れてしまった! – lukieleetronic

関連する問題