C++ Iterator class - c++

class ZoningIter
{
private:
CTile::Zonings mZoning;
CCity *mCity;
int mPos; ///< Position in the collection
public:
ZoningIter(CCity *tile, int pos, CTile::Zonings zoning) : mCity(tile), mPos(pos), mZoning(zoning)
{
while (mPos < mCity->mTiles.size())
{
if (mCity->mTiles[mPos]->GetZoning() == mZoning)
break;
else
mPos++;
}
}
bool operator!=(const ZoningIter &other) const
{
return mPos != other.mPos;
}
std::shared_ptr<CTile> operator *() const
{
return mCity->mTiles[mPos];
}
const ZoningIter& operator++()
{
auto size = mCity->mTiles.size();
auto myzone = mCity->mTiles[mPos]->GetZoning();
while (mPos < size-1)
{
++mPos;
if (mCity->mTiles[mPos]->GetZoning() == mZoning)
break;
}
return *this;
}
};
Not sure what am I doing wrong in this iterator. This class Iterator is suppose to loop over the class CCity and compare the tiles coming back with the ones that I am looking for.
one issue that I can see it run into an infinite loop not sure how to fix it ? any ideas?

You are running into an infinite loop because your operator++ won't increment to one past all elements, also known as an end-iterator.
while (mPos < size-1) // <-- This line is wrong, stops too early
It masks the error in the check-for-success you do afterwards.
Anyway, it should start with an increment, and then check whether it can and should loop.
A corrected version, with both bugs removed:
const ZoningIter& operator++() {
while( ++mPos < mCity->mTiles.size()
&& mCity->mTiles[mPos]->GetZoning() != mZoning)
{}
return *this;
}
Also, the return-type of operator*() should be const std::shared_ptr<CTile>&, the caller can make a copy if needed.

Related

Custom Vector class jump on uninitialised value

im trying to create a custom vector class in c++. As im quite new to the whole c++ world im a bit confused. Valgrind is telling me that im doing a jump on an uninitialised value. However I don't know why that appears.
My personal answer would be alright i dont initialize any values in the normal
vector(unsigned startCap = 1, unsigned increment = 0):
width(increment),
cap(startCap),
field(new T[startCap]){};
However im completely clueless as this happens during the use of my operator= where i compare *this with my input.
Maybe someone could be so clever and tell me what i should do here.
template<class T>
class vector{
public:
vector(unsigned startCap = 1, unsigned increment = 0):
width(increment),
cap(startCap),
field(new T[startCap]){};
~vector(){
delete[] field;
};
vector(const vector& x):width(0),cap(1),field(new T[1]){
copyHelper(x);
};
vector(const T& x):width(0),cap(1),field(new T[1]){
push_back(x);
}
void copyHelper(const vector &v) {
for(unsigned i = 0; i < next; ++i) {
setField(v,i);
}
}
void push_back(T x){
if(next >= cap)
resize();
getField()[next++]=x;
}
T& operator[](unsigned x){
return getField()[x];
};
const T& operator[](unsigned x) const {
if(x < size()) {
return getField()[x];
}
}
bool operator==(const vector<T> v) const{
if((getCap() == v.getCap()) && (getNext() == v.getNext()) && (getWidth() == v.getWidth())){
for(unsigned i = 0; i<v.getCap();++i){
if(getField()[i] != v.getField()[i]){
return false;
}
}
return true;
}else{
return false;
}
}
vector& operator=(const vector& x){
if(*this == x)
return *this;
setCap(x.getCap());
setNext(x.getNext());
copyHelper(x);
return *this;
};
T* getField() const{
return field;
}
void setField(const vector<T>& x,unsigned i){
field[i] = x.getField()[i];
}
void setField(const T* x){
field = x;
}
...
private:
void resize(){
const unsigned newCap = width == 0 ? cap * 2 : cap + width;
T* newField = new T[newCap];
for(unsigned i = 0; i<cap;++i){
newField[i] = field[i];
}
delete[] field;
cap = newCap;
field = newField;
}
const unsigned width;
unsigned cap;
unsigned next = 0;
T* field = nullptr;
};
There are a lot of problems with this code.
Most notably, your operator== has some logic errors in it. But more importantly, if(*this == x) in operator= should be if(this == &x) instead.
Also, your copy constructor is implemented wrong. It allocates room for only 1 element, but then attempts to copy as many elements are in the source vector.
And, your const operator[] is missing a return or throw if the input x is out of bounds. It should not be performing anyvbounds checking at all, like your non-const operator[].
And, setField() looks like a memory leak waiting to happen.
And, we can't even see the rest of your implementation, so there is no way to see if there are other problems.

To clarify concept of relational operator overloading (Debugging help needed)

Let me tell you guys I am beginner to c++.
For educational and learning purpose I have created my own string class named MyString. As per instructions from my instructor I am not allowed to use standard library functions to compare two strings.
MyString class contains char type pointer and integer type variable that holds length of string i.e:
class MyString{
char *str; int len;
public:
MyString(){
len = 1;
str = new char[len];
str[len - 1] = '\0';
}
MyString(char *p){
int count = 0;
for (int i = 0; p[i] != '\0'; i++){
count++;
}
len = count;
str = new char[len];
for (int i = 0; i < len; i++){
str[i] = p[i];
}
}
int length(){
return len;
}
bool operator < (MyString obj){
char temp;
if (len < obj.len){ return true; }
if (len>obj.len){ return false; }
if (this->len == obj.len){
for (int i = 0; i < len; i++){
if (this->str[i] < obj.str[i])
{
return true;
}
}
}
}
bool operator > (MyString obj) {
if (len > obj.len) {
return true;
}
if (len<obj.len) {
return false;
}
if (this->len == obj.len)
{
for (int i = 0; i < this->len; i++) {
if (this->str[i] > obj.str[i]) {
return true;
}
}
}
}
bool operator == (MyString obj) {
int count = 0;
if (this->len == obj.len){
for (int i = 0; i < this->len; i++) {
if (this->str[i] == obj.str[i]) {
count++;
}
}
if (count == len) {
return true;
}
}
}
char & operator[](int i) {
return str[i];
}
};
Here is main
int main()
{
char arr1[30], arr2[30];
cout << "Enter first MyString: ";
cin.get(arr1, 30);
cin.ignore();
cout << "Enter second MyString: ";
cin.get(arr2, 30);
MyString s1(arr1); //parametrized constructor
MyString s2(arr2);
cout << "Length of s1:" << s1.length() << endl;
cout << "Length of s2:" << s2.length() << endl;
if (s1<s2) // < operator overloaded
cout << "s1 < s2" << endl;
else if (s1>s2) // > operator overloaded
cout << "s1 > s2" << endl;
else if (s1 == s2) // == operator overloaded
cout << "s1 == s2" << endl;
return 0;
}
My algo for comparing two strings is:
i).First check length of two strings if len(length of s1) is less than obj.len(length of s2) than it returns true.
ii).if lengths are equal, compare for each element of s1 char array with s2 char array.Even if one of element of s1 char array is less than that s2 char array element (in ASCII) than return true otherwise return false.
The problems is whenever program executes, on console it shows "s1< s2" no matter if two strings passed are equal .
You're trying to write simple classes that allocate resources. This is a very important skill to have. What you've written so far has some good code, but also a lot of mistakes. The main errors are
Wrong algorithm for operator<. In your code "hello" < "goodbye" which is incorrect
Missing return statements.
Lack of destructor, so your class leaks memory.
Once you add a destructor you will also need a copy constructor and copy assignment operator otherwise your code will crash by freeing the same memory twice, this is known as the rule of three. Google it as it's perhaps the most important piece of C++ advice you'll read.
Lack of awareness of const correctness.
Lack of awareness of pass by reference.
Less than ideal signatures for your overloaded operators.
Missing some important methods on your class
Missing a few implementation tricks.
Putting all that together here an implementation of your class following the rules you've been given, with a few comments as well
class MyString {
char *str; int len;
public:
// default constructor should create a empty string, i.e. a zero length string
MyString() {
len = 0;
str = new char[len];
}
// contents of p are not changed so make it const
MyString(const char *p) {
int count = 0;
for (int i = 0; p[i] != '\0'; i++){
count++;
}
len = count;
str = new char[len];
for (int i = 0; i < len; i++){
str[i] = p[i];
}
}
// destructor, frees memory
~MyString() {
delete[] str;
}
// copy constructor, similar to the above except it starts from a MyString
MyString(const MyString& o) {
len = o.len;
str = new char[len];
for (int i = 0; i < len; i++){
str[i] = o.str[i];
}
}
// swap method, efficient exchange of two strings
void swap(MyString& o)
{
int t1 = o.len;
o.len = len;
len = t1;
char* t2 = o.str;
o.str = str;
str = t2;
}
// assignment operator, uses copy and swap idiom
MyString& operator=(MyString o) {
swap(o);
return *this;
}
// length does not modify the string, so it should be decalred const
int length() const {
return len;
}
char& operator[](int i) {
return str[i];
}
// need a const version of operator[] as well, otherwise you won't be able to do [] on a const string
char operator[](int i) const {
return str[i];
}
};
// operator< should be a function not a class method. This is the only way to get
// C++ to treat the two arguments symmetrically. For instance with your version
// "abc" < str is not legal, but str < "abc" is. This oddity is because C++ will
// not implicitly create a MyString object to call a MyString method but it will implicitly
// create a MyString object to pass a parameter. So if operator< is a function you will
// get implicit creation of MyString objects on either side and both "abc" < str and
// str < "abc" are legal.
// You also should pass to parameters by const reference to avoid unnecessary
// copying of MyString objects.
// Finally this uses the conventional algorithm for operator<
bool operator<(const MyString& lhs, const MyString& rhs) {
for (int i = 0; ; ++i)
{
if (i == rhs.length())
return false;
if (i == lhs.length())
return true;
if (lhs[i] > rhs[i])
return false;
if (lhs[i] < rhs[i])
return true;
}
}
// This is the easy way to write operator>
bool operator>(const MyString& lhs, const MyString& rhs) {
return rhs < lhs;
}
// This is the easy way to write operator<=
bool operator<=(const MyString& lhs, const MyString& rhs) {
return !(rhs < lhs);
}
// This is the easy way to write operator>=
bool operator>=(const MyString& lhs, const MyString& rhs) {
return !(lhs < rhs);
}
// operator== is a function not a method for exactly the same reasons as operator<
bool operator==(const MyString& lhs, const MyString& rhs) {
if (lhs.length() != rhs.length())
return false;
for (int i = 0; i < lhs.length(); ++i)
if (lhs[i] != rhs[i])
return false;
return true;
}
// this is the easy way to write operator!=
bool operator!=(const MyString& lhs, const MyString& rhs) {
return !(lhs == rhs);
}
There are countless issues with your code, so I'll provide an improved, commented implementation for you:
class MyString
{
char* str;
unsigned int len; // strings can't have negative length; using unsigned reflects this better
// even better: use size_t; this is the type for the concrete system
// able to cover any allocatable memory size
public:
MyString()
: str(new char[1]), len(1) // prefer initializer list
{
str[0] = 0; // does not matter if you use 0 or '\0', just my personal preference...
}
MyString(char const* p)
// you make a copy of, so have a const pointer (you can pass both const and non-const to)
{
for(len = 1; p[len] != 0; ++len);
// ^ make sure to copy the terminating null character as well!
str = new char[len];
for (unsigned int i = 0; i < len; i++)
{
str[i] = p[i];
}
// or use memcpy, if allowed
}
// OK, above, you allocated memory, so you need to free it again:
~MyString() // if you want to be able to inherit from, it should be virtual;
// strings, though, most likely should not be inherited from...
{
delete[] str;
}
// C++ creates a default copy constructor; this one, however, just copies all members by value
// i. e. copies the POINTER str, but not the memory pointed to, i. e. does not perform a deep copy
// which is what you need, however, to avoid double deletion:
MyString(MyString const& other)
: str(new char[other.len]), len(other.len)
{
for (unsigned int i = 0; i < len; i++)
{
str[i] = other.str[i];
}
}
// similar for assignment; I'm using copy and swap idiom to reduce code duplication here:
MyString& operator=(MyString other)
{
swap(other);
return *this;
}
void swap(MyString& other)
{
char* str = this->str;
unsigned int len = this->len;
this->str = other.str;
this->len = other.len;
other.str = str;
other.len = len;
}
unsigned int length() const
// ^^^^^ allows to retrieve length from a
// const MyString as well!
{
return len;
}
// fine, you can change the character within the string
char& operator[](unsigned int i)
{
return str[i];
}
// but what, if you have a const MyString???
// solution:
char operator[](unsigned int i) const
// ^^^^^
{
return str[i];
}
// you could alternatively return a const reference,
// but char is just too small that a reference would be worth the effort
// additionally: a reference could have the const casted away by user
// which is not possible by returning a copy, so we gain a little of safety as well...
bool operator<(MyString const& other) const
// ^^^^^^
// we don't need a copy and don't want a copy(it would just costs runtime and memory for nothing)!
// -> pass by const reference
// additionally, we want to be able to do comparison on const this as well (see length)
//
{
// have you noticed that you have one and the same code in all of your comparison operators???
// only the comparison itself changes lets have it just a little bit cleverer:
return compare(other) < 0;
}
bool operator>(MyString const& other) const
{
return compare(other) > 0;
}
bool operator==(MyString const& other) const
{
return compare(other) == 0;
}
// and for completeness:
bool operator<=(MyString const& other) const
{
return compare(other) <= 0;
}
bool operator>=(MyString const& other) const
{
return compare(other) >= 0;
}
bool operator!=(MyString const& other) const
{
return compare(other) != 0;
}
// the upcoming space ship operator (<=>) will simplify this, well, OK, but for now, we don't have it yet...
int compare(MyString const& other) const
{
// I decided to compare "abcd" smaller than "xyz" intentionally
// for demonstration purposes; just place your length checks
// back to get your original comparison again
unsigned int pos = 0;
// EDIT: "stealing" john's implementation, as superior to
// mine (with minor adaptions) ...
for (unsigned int pos = 0; ; ++pos)
{
///////////////////////////////////////////////////
// if you have your original length checks placed back above,
// just have the following check instead of the active one:
// if(pos == len) return 0;
if (pos == len)
{
return pos == other.len ? 0 : -pos - 1;
}
if (pos == other.len)
{
return pos + 1;
}
///////////////////////////////////////////////////
if(str[pos] < other.str[pos])
{
return -pos - 1;
}
if(str[pos] > other.str[pos])
{
return pos + 1;
}
}
return 0;
}
// WARNING: above code has yet an issue! I wanted to allow (for demonstration)
// to return positional information so that we not only see the result of comparison
// but can conclude to at WHERE the two strings differ (but need 1-based offset for to
// distinguish from equality, thus addition/subtraction of 1);
// however, on VERY large strings (longer than std::numeric_limits<int>::max()/-[...]::min()), we get
// signed integer overflow on the implicit cast, which is undefined behaviour
// you might want to check against the limits and in case of overflow, just return the limits
// (leaving this to you...)
// alternative: just return -1, 0, +1, the issue is gone as well...
};
OK, you now could just copy this code, strip the comments and present it as "your" solution. This is not what I intended this answer for! Take your time and read my comments carefully – you can learn quite a bit from...
Finally: there is yet another improvement possible: Before C++11, you could only copy data, if passing objects by value. Since C++, we additionally can move data from one object into another one – however, the type needs to support move semantics. You can do so by additionally providing a move constructor and copy assignment:
MyString(MyString&& other)
: str(nullptr), len(0)
{
// delete[]'ing nullptr (in other!) is OK, so we don't need
// to add a check to destructor and just can swap again...
swap(other);
}
MyString& operator=(MyString&& other)
{
// and AGAIN, we just can swap;
// whatever this contained, other will clean it up...
swap(other);
return *this;
}
You might be interested in further reading:
rule of three
rule of five
copy and swap idiom
In your function,
bool operator < (MyString obj){
I see no way to return false at the end!
It only returns true if it reach the 3rd if.
In addition, as others mentioned, the length does not imply the comparison in the way that you implemented.
Just a comment: Your code is prone to memory leak. It allocates but does not release the memory.
This code has lots of mistakes:
No copy constructor and copy is created
Missing destructor saves the day (memory leak, but thanks to that you do not have a crash for point 1)
len = 1 for empty string (default constructor).
MyString(char *p) do not add terminating character
not using const MyString &obj (unneeded copies).
missing return values at the end of various branches of methods
bool operator < (const MyString &obj) {
if (len < obj.len) {
return true;
}
if (len>obj.len) {
return false;
}
for (int i = 0; i < len; i++) {
if (this->str[i] != obj.str[i]) {
return this->str[i] < obj.str[i];
}
}
return false;
}

Find out if the next integer in a stack array is the same

So I am trying to implement this method to know if an integer occurs twice consecutively in my stack array. This integer is taken as a parameter and I want to know if it happens twice consecutively. Unfortunately, my method always returns false, do you know why?
template<class T>
bool stack<T>::isConsecutive( const T & data ) const{
bool flag=false;
for (size_t i = 0; i < _top; i++) {
if(data==elements[i] && elements[i]==elements[i+1]){
flag=true;
}
else {
flag=false;
}
}
return flag;
}
try this
template<class T>
bool stack<T>::isConsecutive( const T & data ) const{
bool flag=false;
for (size_t i = 0; i < _top-1; i++) {
if(data==elements[i] && elements[i]==elements[i+1]){
return true;
}
}
return flag;
}
this will work i guess .

Logical Comparison == operator overload

I need to do some logical comparison and return a boolean answer.
Here is the code from the .cpp file:
bool MyString::operator==(const MyString& other)const
{
if(other.Size == this.Size)
{
for(int i = 0; i < this.Size+1; i++)
{
if(this[i] == other[i])
return true;
}
}
else
return false;
}
Here is what is called from main.cpp file:
if (String1 == String4)
{
String3.Print ();
}
else
{
String4.Print ();
}
Here are there compiling errors I get:
error: request for member `Size` in `this`, which is of non-class type `const MyString* const`
error: no match for `operator[]` in `other[i]`
this is a pointer, hence you have to dereference it:
this->Size;
Also I think that logic of your operator== is flawed - here, it returns true if any of characters is equal to character on same position in second string. Change your loop to
for(int i = 0; i < this->Size+1; i++)
{
if(this[i] != other[i])
return false;
}
and put return true; instead of last part of your code (else clause) to compare entire strings.
As Seth mentioned, you can't use operator[] on this as above - this way it's treated as array (i.e. this[i] is really *(this + i) - so not what's you are thinking it is). Access your internal storage member instead.
Problems with your code:
this[i]: You apparently want to access the ith character of the string here. This isn't doing that. Assuming your class overloads operator[], you want (*this)[i]. Alternatively, you could directly access the internal representation of the string.
if(this[i] == other[i]) return true;: Think about what this means with respect to comparing the strings "A1" and "AB".
for () {...}: What happens when you exit the loop? You need to return something if the comparisons manage to make it through the loop without returning.
You haven't specified if you can use the C++ standard algorithms or not.
Here you have illustrated both versions, using hand-written loop and std::equal algorithm:
//#define USE_STD_ALGORITHM 1 // uncomment to enable std::equal version
#include <cassert>
#include <algorithm>
#include <stdexcept>
// NOTE: partial simplest definition for the test and presentation purposes only.
struct MyString
{
MyString(char const* s, std::size_t size) : data(s), Size(size) {}
char const& operator[](std::size_t index) const;
bool operator==(const MyString& other) const;
private:
char const* data;
std::size_t Size;
};
char const& MyString::operator[](std::size_t index) const
{
if (index < Size)
return data[index];
throw std::out_of_range("index invalid");
}
bool MyString::operator==(const MyString& other) const
{
if (this->Size == other.Size)
{
#ifdef USE_STD_ALGORITHM
return std::equal(data, data+Size, other.data);
#else
bool equal = true;
for(std::size_t i = 0; i < this->Size; ++i)
{
if((*this)[i] != other[i])
{
equal = false;
break;
}
}
return equal;
#endif
}
return false;
}
int main()
{
char const* a = "abc";
char const* b = "abc";
MyString sa(a, 3);
MyString sb(b, 3);
assert(sa == sb);
char const* c = "adc";
MyString sc(c, 3);
assert(!(sa == sc));
char const* d = "ab";
MyString sd(d, 2);
assert(!(sa == sd));
}
Good luck!

operators on Iterators in C++

I am porting an old code base to OSX.
I have the following snippet of code:
FxLayerList::iterator lastVisible = NULL;
for (FxLayerList::iterator iter = mBranch.begin(); iter != mBranch.end(); iter++) {
if ( (*iter)->IsVisible() && !(*iter)->IsBypass()) {
lastVisible = iter;
}
}
if (lastVisible != NULL && (*lastVisible)->GetGeneratedImage()) {
I get an error that says: error: no match for 'operator!=' in 'lastVisible != 0'
I dont follow, I thought operations like != and ==, etc were standard operations. Why the complaint from the compiler?
UPDATE: I am trying to understand the comparison of objects. What if the code is like this:
FxBool FxLayerList::Contains(FxLayer *layer) const
{
for (FxLayerList::const_iterator iter=this->begin(); iter != this->end(); iter++)
{
if ((*iter) == layer) {
return true;
}
}
return false;
}
with errors like: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
What is the core concept I am missing?
Update 2:
// FxSmartPtr is a smart pointer that is also typed for each class, avoiding the need for any casting.
// Setting an FxSmartPtr to NULL actually kills the memory that it's pointing to as well.
template <class eachClass>
class FxSmartPtr
{
public:
// Construction
// Default constructor makes an empty container.
FxSmartPtr(void) : mPtr(NULL) {}
// Construction with a ptr adds one reference to it.
FxSmartPtr(eachClass *ptr) : mPtr(ptr) { this->Reference(); }
// Copy construction means that both smart pointers end up with a reference to the object.
FxSmartPtr(const FxSmartPtr & inPtr) :mPtr(NULL) { FrAssignRef(mPtr,(eachClass *)inPtr.mPtr); }
// Default construction
FxSmartPtr(FxConstructArg cons) { if (cons == FcNew) mPtr = new eachClass(); }
FxSmartPtr(FxConstructArg cons,eachClass *ptr) { if (cons == FcNew) mPtr = ptr; }
// Destructor removes only the one reference that we own.
~FxSmartPtr() { this->Dispose(); }
// Most important and common use is via assignment. References are always safely balanced.
// AssignReference safely replaces one reference counted ptr with another.
static inline eachClass * FrAssignRef(eachClass *& to, eachClass * from)
{ if (from) from->AddReference(); if (to) to->RemoveReference(); to = from; return to; }
// If you assign a pointer to this object we add one reference count to it.
const FxSmartPtr<eachClass> & operator = (const eachClass *ptr)
{ FrAssignRef(mPtr,(eachClass *)ptr); return *this; }
// Replace our referenced object with a reference added to the incoming one.
const FxSmartPtr<eachClass> & operator = (const FxSmartPtr & inPtr)
{ FrAssignRef(mPtr,(eachClass *)inPtr.mPtr); return *this; }
// Assignment to a dumb pointer takes/gives no references.
operator eachClass * (void) const
{ return mPtr; }
eachClass * operator->(void)
{ if (mPtr != NULL) if (mPtr->GetRefCount() < 1 || mPtr->GetRefCount() > 10000) ASSERT(0); return mPtr; }
const eachClass * operator->(void) const
{ if (mPtr != NULL) if (mPtr->GetRefCount() < 1 || mPtr->GetRefCount() > 10000) ASSERT(0); return mPtr; }
// Explicit assignment and object transfers
// Get() - return ptr with no reference
eachClass * Get(void) const
{ return mPtr; }
eachClass * GetPtr(void)
{ return mPtr; }
// Own() - return ownership with ptr
eachClass * Own(void)
{ if (mPtr) mPtr->AddReference(); return mPtr; }
// Set() - we take our own reference on your object
FxSmartPtr<eachClass> & Set(eachClass * ptr)
{ FrAssignRef(mPtr, ptr); return *this; }
// Take() - you give us your reference
FxSmartPtr<eachClass> & Take(eachClass * ptr)
{ FrDispose(mPtr); mPtr = ptr; return *this; }
// Comparison operators compare the pointers contained in each
FxBool operator == (const FxSmartPtr & inPtr) const
{ return (mPtr == inPtr.mPtr); }
FxBool operator == (const eachClass * inPtr) const
{ return (mPtr == inPtr); }
FxBool operator != (const FxSmartPtr & inPtr) const
{ return (mPtr != inPtr.mPtr); }
FxBool operator != (const eachClass * inPtr) const
{ return (mPtr != inPtr); }
// Reference() and Dispose() change the normal reference count. If you use these then
// you end up having to count references externally.
// Safely take a reference if the ptr is not nil
void Reference(void) { if (mPtr != NULL) mPtr->AddReference(); }
// Safely dispose one reference count.
void Dispose(void) { if (mPtr != NULL)
// JASON/INDIE - SLACKMOEHRLE#GMAIL.COM
// { ULONG refs = mPtr->GetRefCount(); mPtr->RemoveReference(); if (refs <= 1) mPtr = NULL; } }
{ FxUInt32 refs = mPtr->GetRefCount(); mPtr->RemoveReference(); if (refs <= 1) mPtr = NULL; } }
protected:
eachClass *mPtr;
};
It looks that lastVisible is an object rather than just a pointer. If you compare some object with something, then it has to have the appropriate operator.
Maybe this would compile?
FxLayerList::iterator lastVisible = mBranch.end();
for (FxLayerList::iterator iter = mBranch.begin(); iter != mBranch.end(); iter++)
{
if ( (*iter)->IsVisible() && !(*iter)->IsBypass())
{
lastVisible = iter;
}
}
if (lastVisible != mBranch.end() && (*lastVisible)->GetGeneratedImage())
{ ...
Or if FxLayerList is just a collection of pointers to FxLayer, this would be more straightforward:
FxLayer *lastVisible = NULL;
for (FxLayerList::iterator iter = mBranch.begin(); iter != mBranch.end(); iter++)
{
if ( (*iter)->IsVisible() && !(*iter)->IsBypass())
{
lastVisible = *iter;
}
}
if (lastVisible != NULL && lastVisible->GetGeneratedImage())
{ ...
Answer to UPDATE: see my comment below. The problem (compiler error message) can be solved by explicitly retrieving the pointer from the "smart" pointer:
FxBool FxLayerList::Contains(FxLayer *layer) const
{
for (FxLayerList::const_iterator iter=this->begin(); iter != this->end(); iter++)
{
if (iter.Get() == layer) {
return true;
}
}
return false;
}
The standard operators are overloadable to support directly comparing objects, but out of the box they wouldn't know what to compare (I think the default behaviour would be to simply compare the object's address, but your error seems to contradict that).
In any event, How to compare two objects (the calling object and the parameter) in a class? seems to be a very similar problem.
Within your class you should probably add in something like what Alexander suggested above:
int Date :: Compare (const Date& d) {
if (year<d.year) {
return -1;
}
}
bool operator == (const Date& d) const {
return !Compare(d);
}
Of course modified to suit your comparison requirements.