Does anyone know what could cause this behavior? or if this is bug in msvc++ 7.1?
Code:
class WriteOid : public WriteNode
{
std::ostream& m_os;
public:
WriteOid(std::ostream& out);
void operator()(OidValueType value, const OidMap& oidMap)
{
m_os << typeid(*value.first).name() << std::endl; // write class identifier
m_os << value.second << std::endl; // write unique object id
}
};
class Serialization
{
friend class WriteObject;
public:
typedef counted_ptr<Serialization> Ptr;
virtual Serialization* Clone() const = 0;
virtual void Accept(Visitor* visitor) = 0;
virtual void SerializeAll(std::ostream& os);
private:
OidVisitor::Ptr BuildOidTable();
InvOid::Ptr LoadOidTable(std::istream& is);
void SerializeOidTable(OidVisitor::Ptr v, std::ostream& out);
virtual void Serialize(std::ostream& os, const OidMap& oidMap) = 0;
//static std::map<std::string, Serialization*> m_typeMap;
};
Switching the order of these two classes seems to corrupts the type_info data from the virtual table because the type_info.name() of a class derived from Serialization is returning "class serial::Serialization" instead of the derived class. Yet before the parameter is passed into to operator()(OidValueType... typeinfo(*value.first).name() returns the correct string. Thus this problem seems to be because of the order of template instantiation. If the call to operator()() occurs before Serialization in the sourcefile, the problem occurs., and so writing WriteOid like this does not exhibit the problem.
PHP Code:
class WriteOid : public WriteNode
{
std::ostream& m_os;
public:
WriteOid(std::ostream& out);
void operator()(OidValueType value, const OidMap& oidMap);
};
class Serialization
{
friend class WriteObject;
public:
typedef counted_ptr<Serialization> Ptr;
virtual Serialization* Clone() const = 0;
virtual void Accept(Visitor* visitor) = 0;
virtual void SerializeAll(std::ostream& os);
private:
OidVisitor::Ptr BuildOidTable();
InvOid::Ptr LoadOidTable(std::istream& is);
void SerializeOidTable(OidVisitor::Ptr v, std::ostream& out);
virtual void Serialize(std::ostream& os, const OidMap& oidMap) = 0;
//static std::map<std::string, Serialization*> m_typeMap;
};
inline void WriteOid::operator()(OidValueType value, const OidMap& oidMap)
{
m_os << typeid(*value.first).name() << std::endl; // write class identifier
m_os << value.second << std::endl; // write unique object id
}
Though writing it like this will
Code:
class WriteOid : public WriteNode
{
std::ostream& m_os;
public:
WriteOid(std::ostream& out);
void operator()(OidValueType value, const OidMap& oidMap);
};
inline void WriteOid::operator()(OidValueType value, const OidMap& oidMap)
{
m_os << typeid(*value.first).name() << std::endl; // write class identifier
m_os << value.second << std::endl; // write unique object id
}
class Serialization
{
friend class WriteObject;
public:
typedef counted_ptr<Serialization> Ptr;
virtual Serialization* Clone() const = 0;
virtual void Accept(Visitor* visitor) = 0;
virtual void SerializeAll(std::ostream& os);
private:
OidVisitor::Ptr BuildOidTable();
InvOid::Ptr LoadOidTable(std::istream& is);
void SerializeOidTable(OidVisitor::Ptr v, std::ostream& out);
virtual void Serialize(std::ostream& os, const OidMap& oidMap) = 0;
};