質問

in the code below, I get a std::bad_cast exception thrown when casting derived.properties_ from BaseProperties to DerivedProperties. Looking at the code, it seems to me like something is going wrong when intialising the BaseProperties with a reference to the DerivedProperties in the Base class constructor.

What I am trying to achieve is a simple UI where Base is essentially my Component interface and Derived is anything that is considered a Component. It seems like a fair assumption that Components may have different properties but have some similar ones, such as size and position.

Can anyone offer any suggestions as to how best to achieve my aim?

#include <iostream>
#include <string>

// Properties for all objects of Base type
class BaseProperties {
public:
  BaseProperties( std::string baseProperty ):
    baseProperty_( baseProperty ) { }

  virtual ~BaseProperties(  ) {  }
  std::string getBaseProperty(  ) { return baseProperty_; }

protected:
  std::string baseProperty_;
};

// Properties specific to objects of Derived type
class DerivedProperties: public BaseProperties {
public:
  DerivedProperties( std::string baseProperty, std::string derivedProperty ):
    BaseProperties( baseProperty ),
    derivedProperty_( derivedProperty ) {  }

  std::string getDerivedProperty(  ) { return derivedProperty_; }

private:
  std::string derivedProperty_;
};

class Base {
public:
  Base( BaseProperties& properties ):
    properties_( properties ) {  }

  virtual ~Base(  ) {  }

protected:
  BaseProperties& properties_;
};

class Derived : public Base {
public:
  Derived( DerivedProperties properties ):
    Base( properties ) {  }

  friend std::ostream & operator << ( std::ostream& out, const Derived& derived );
};

std::ostream & operator << ( std::ostream& out, const Derived& derived ) {  
  return out << derived.properties_.getBaseProperty(  ) << ", "
             << dynamic_cast< DerivedProperties& >( derived.properties_ ).getDerivedProperty(  );
}

int main(  ) {
  Derived derived( DerivedProperties( "BaseProperty", "DerivedProperty" ) );

  std::cout << derived << std::endl;
  return 0;
}
役に立ちましたか?

解決

Your derived class should take a DerivedProperty& as parameter, similar to how your Base class does it:

class Derived : public Base {
public:
  Derived( DerivedProperties& properties ):
    Base( properties ) {  }

  friend std::ostream & operator << ( std::ostream& out, const Derived& derived );
};

Since you're not taking a reference as constructor parameter but an actual object, you're actually storing a reference to a temporary object, that does not exist anymore once the constructor has exited.

他のヒント

When the Derived constructor ends, the properties argument will be destroyed. However, you've stored a reference to that object, so that reference is now left dangling. Instead, you should make the properties_ member not a reference.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top