Я портирую этот код из Visual C ++ 6.0 (он также работал со старым GCC ++) на Visual Studio 2010 C ++.Код компилируется, но выдает исключение.
У меня есть базовый класс, CncMatchedQueryAtom.Этот класс содержит совпадения различных типов целевых атомов (это приложение сопоставления графиков) для 99% случаев, когда между запросом и целью существует однозначное совпадение.Это обрабатывается производным классом CncMatchedQueryAtomSimple.Этот класс отлично работает.Проблема в том, что некоторые атомы запросов соответствуют группам атомов, это обрабатывается классом CncMatchedQueryAtomGroup.Этот класс содержит вектор с подобранными атомами.Я хочу, чтобы класс итератора, определенный в базовом классе, инкапсулировал векторный итератор в производный класс так, чтобы begin () возвращал вектор begin (), а end - конец вектора ().Старая версия имеет проблемы с end () во время выполнения, потому что она выполняет преобразование следующим образом:
return & * group.end ();
Что больше не разрешено в Visual C ++. Так какбазовый класс может указать итератор, который могут реализовать производные классы?Это не кажется мне очевидным, но я новичок в C ++.И не то, что опытные разработчики C ++, с которыми я работаю, тоже знают.
По сути, я хочу, чтобы в базовом классе были методы, обеспечивающие функции начала и конца, которые реализуют производные классы.
Вот код:
class CncMatchedQueryAtom
{
protected:
int notBlockAllocated;
public:
int allocateIndividually() const
{
return notBlockAllocated;
}
const CncAtom *queryAtom;
CncAtom *queryAtomVolitile() const
{
return (CncAtom*)queryAtom;
}
// set when the class has been allocated by newing
// intialize all default constructors to be notBlockAllocated
CncMatchedQueryAtom()
: notBlockAllocated(1)
, queryAtom(NULL) // i don't think this needs to be initialized to null
{
}
CncMatchedQueryAtom(int noBlock)
: notBlockAllocated(noBlock)
, queryAtom(NULL) // i don't think this needs to be initialized to null
{
}
// may not need this now that it's a virtual!
CncMatchedQueryAtom(const CncMatchedQueryAtom &that)
: queryAtom(NULL)
{
*this = that;
}
// this needs to be virtual so when delete CncMatchedQueryAtom is called
// the virtual calss members are destructed too
virtual ~CncMatchedQueryAtom()
{
}
virtual void dump() const =0;
virtual void clearMapping() =0;
virtual CncMatchedQueryAtom *newCopy() const =0;
virtual void coverHits(class CncTarget *) const = 0;
// iterates over all matched target atoms for this query atom
class iterator
{
private:
CncMatchedTargetAtom *ptr;
public:
iterator()
{
}
iterator(const CncMatchedTargetAtom *targetAtom) // constructor from a target ptr
:ptr((CncMatchedTargetAtom *)targetAtom)
{
}
iterator(const iterator &oldOne)
:ptr(oldOne.ptr)
{
}
~iterator()
{
}
int operator==(const iterator &that) const
{
return ptr==that.ptr;
}
int operator!=(const iterator &that) const
{
return ptr!=that.ptr;
}
const CncMatchedTargetAtom &operator*() const
{
return *ptr;
}
iterator operator++(int NotUsed) // post increment
{
iterator returnValue(*this);
++ptr;
return returnValue;
}
iterator &operator++() // pre increment
{
++ptr;
return *this;
}
int operator<(const iterator &rhs) const
{
return (this->ptr < rhs.ptr);
}
CncMatchedTargetAtom *operator->()
{
return ptr;
}
};
virtual iterator begin() const =0;
virtual iterator end() const =0;
virtual int size() const = 0;
virtual double molecularWeight() const = 0;
const CncAtom *getFirstTargetAtom() const
{
return (*begin()).matchedTargetAtom;
}
CncAtom *getFirstTargetAtomVolitile() const
{
return (CncAtom*)getFirstTargetAtom();
}
}; // class CncMatchedQueryAtom
class CncMatchedQueryAtomSimple : public CncMatchedQueryAtom
{
public:
// we need a constructor here since this is allocated with blockAlloc
CncMatchedQueryAtomSimple()
: CncMatchedQueryAtom(0)
{
}
// we use simple.targetAtom as a temporary variable
// used to pass to matching functions
CncMatchedTargetAtom simple;
void clearIt()
{
queryAtom=NULL;
notBlockAllocated=0;
}
// if queryAtom is an element-type atom (or Lp or A atom)
void dump() const;
void clearMapping()
{
}
CncMatchedQueryAtom *newCopy() const
{
// since this is usually not allocatedIndividually I'll set
// the notBlockAllocatedFlag on the copy to be sure if this
// does happen it will individually deallocate it
CncMatchedQueryAtomSimple *retVal = new CncMatchedQueryAtomSimple(*this);
retVal->notBlockAllocated = 1;
return (CncMatchedQueryAtom *)retVal;
}
void coverHits(class CncTarget *) const;
iterator begin() const
{
return &simple;
}
iterator end() const
{
return &simple+1;
}
int size() const
{
return 1;
}
double molecularWeight() const
{
return CncMolGetAtomicMassAve(simple.matchedTargetAtom->getAtomicNumber());
}
}; // class CncMatchedQueryAtomSimple
class CncMatchedQueryAtomGroup : public CncMatchedQueryAtom
{
public:
// if queryAtom is an R- or X-group searching for
std::vector<CncMatchedTargetAtom> group;
void dump() const;
void clearMapping()
{
group.clear();
}
CncMatchedQueryAtom *newCopy() const
{
return new CncMatchedQueryAtomGroup(*this);
}
void coverHits(class CncTarget *) const;
iterator begin() const
{
return &*group.begin();
}
iterator end() const
{
// this is a hack, works with Visual C++ 6.0 and older GCC++ but not VS C++ 2010
return &*group.end(); // Throws error at runtime! Iterator Not Dereferencable
}
int size() const
{
return group.size();
}
double molecularWeight() const
{
double sum=0;
std::vector<CncMatchedTargetAtom>::const_iterator q;
for (q=group.begin()
; q!=group.end()
; ++q)
{
sum += CncMolGetAtomicMassAve(q->matchedTargetAtom->getAtomicNumber());
}
return sum;
}
}; // class CncMatchedQueryAtom
Пример того, как называется итератор:
// Sample call to the iterator
// (*elem)->getMatchedAtom() returns a CncMatchedQueryAtom *
CncMatchedQueryAtom::iterator atomMatched;
// welp it looks like we have to do these
//(*elem)->getFirstTargetAtom
for (atomMatched=(*elem)->getMatchedAtom()->begin()
; atomMatched!=(*elem)->getMatchedAtom()->end() // Runtime exception here!
; ++atomMatched)
{
existenceFingerprint.setBit(
atomMatched->matchedTargetAtom->indexInStructure);
}
Спасибо, надеюсь, это не слишком много кода ...