Link to home
Start Free TrialLog in
Avatar of AssafLavie
AssafLavie

asked on

vector<CMyClass>

Hi.
If I want to use a vector<> for a type CMyClass, CMyClass has to overload some operators (=, ==, <).
Can anyone give me an example of how this is done. I'm looking for the simplest implementation.
Here's CMyClass's definition:
CMyClass
{
private:
    int m_nID;
public:
    int GetID() { return m_nID; };
};

I want to use:
vector<CMyClass> v1;

Can anyone complete this code?
Thanks.

Avatar of Zoppo
Zoppo
Flag of Germany image

Hi AssafLavie,

somehow like this:

CMyClass
{
private:
 int m_nID;
public:
 int GetID() { return m_nID; };
 CMyClass& operator = (CMyClass& src)
 {
  if ( this != &src )
   m_nID = src.m_nID;
 }
 BOOL operator == (CMyClass& src)
 {
  if ( m_nID == src.m_nID )
   return TRUE;
  return FALSE;
 }
 BOOL operator < (CMyClass& src)
 {
  if ( m_nID < src.m_nID )
   return TRUE;
  return FALSE;
 }
 // perhaps you need a copy ctor ...
 CMyClass( CMyClass& src )
 {
  (*this) = src;
 }
};

hope that helps,

ZOPPO
Avatar of jasonclarke
jasonclarke

Depends what you want to do with it.  To just put it in a vector nothing extra is required.

Here is some code that does some stuff with a vector of CMyClass.  (the operator== is only required for the find algorithm):

#include <vector>
#include <algorithm>

using namespace std;

class CMyClass
{
private:
    int m_nID;
public:
    CMyClass(int id) : m_nID(id) {}
    int GetID() { return m_nID; };

    bool operator==(const CMyClass& rhs)
    { return m_nID == rhs.m_nID; }
};



void main()
{
    vector<CMyClass> v1;

    CMyClass mc1(12);
    CMyClass mc2(8);

    v1.push_back(mc1);
    v1.push_back(mc2);

    v1[0].GetID(); // Calls getID on mc1

    // Iterate over the collection using vector iterator
    vector<CMyClass>::iterator it = v1.begin();
    while (it != v1.end())
    {
        // Do something with value
        (*it).GetID();
        ++it;
    }

    // Iterate over the collection using vector indexing
    for (int i=0; i<v1.size(); i++)
    {
        v1[i].GetID();
    }

    // Call an STL algorithm
    vector<CMyClass>::iterator j = std::find(v1.begin(), v1.end(), 8);
    if (j != v1.end())
    {
        // Found it!
        (*j).GetID();
    }
}
Avatar of AssafLavie

ASKER

Thanks for your comments. I turns out I only needed a copy ctor and a = operator.
I am having some trouble with the operator=:
CMyClass
{
....
CMyClass& operator=(CMyClass& src)
{
....
return this; // This won't compile.
}

I need to return a reference to the modified object, but &this or this do not compile. I'm getting something like:
"Cannot convert from 'class CMyClass *const ' to 'class CMyClass &'" (for "return this").
Why is that?
Oh, ups, sorry, I missed it:

CMyClass& operator = (CMyClass& src)
{
 if ( this != &src )
  m_nID = src.m_nID;
 return (*this);
}

ZOPPO
It should be

   ...
   return *this; // the asterix!
Thanks! That helped.
But the vector is still giving my trouble.
The copiler complains: "CMyClass: no copy ctor available".
This is because the parameter to the copy ctor method is of type "CMyClass&" and not "const class CMyClass&" (as the vector demands I guess).

I tried defining the copy ctor and the operator with "const class..." types - but then, the compiler won't let me access the public methods of the src parameter saying: "'GetID' : cannot convert 'this' pointer from 'const class CMyClass' to 'class CMyClass &'".

Uh!
Any clues?
Thanks! That helped.
But the vector is still giving my trouble.
The copiler complains: "CMyClass: no copy ctor available".
This is because the parameter to the copy ctor method is of type "CMyClass&" and not "const class CMyClass&" (as the vector demands I guess).

I tried defining the copy ctor and the operator with "const class..." types - but then, the compiler won't let me access the public methods of the src parameter saying: "'GetID' : cannot convert 'this' pointer from 'const class CMyClass' to 'class CMyClass &'".

Uh!
Any clues?
try to declare the copy constructor like this:

CMyClass {
....
 CMyClass( CMyClass const& src )
 {
 ...
 }
....
};

hope that helps,

ZOPPO
Well that took care of the vector's complaints, but I still san't compile because I get: "cannot convert 'this' pointer from 'const class CMyClass' to 'class MyClass &" whenever I try to access the public methods of the src parameter.
This is code I've tested for compiliance:

--------------------------------------------------
class CMyClass
{
private:
 int m_nID;
public:
 int GetID() { return m_nID; };
 CMyClass& operator = (CMyClass const& src)
 {
  if ( this != &src )
   m_nID = src.m_nID;
  return (*this);
 }
 BOOL operator == (CMyClass const& src )
 {
  if ( m_nID == src.m_nID )
   return TRUE;
  return FALSE;
 }
 BOOL operator < (CMyClass const& src)
 {
  if ( m_nID < src.m_nID )
   return TRUE;
  return FALSE;
 }
 CMyClass( CMyClass const& src )
 {
  (*this) = src;
 }
 CMyClass( int id )
 {
  m_nID = id;
 }
};

#include <vector>
#include <algorithm>
using namespace std;

int main(int , char* [])
{
//      CTestClass cl;

  vector<CMyClass> v1;
 
  CMyClass mc1(12);
  CMyClass mc2(8);
 
  v1.push_back(mc1);
  v1.push_back(mc2);
....
}
--------------------------------------------------

ZOPPO
Thats because the public methods of the source parameter are probably not const.  

You have a couple of choices with a copy constructor for this:

i) make the used methods const, if they are used in a copy constructor, they probably should be.

ii) bypass the methods and use the internal representation directly.  You can do this in a copy constructor with no problem, so instead of

   m_nID = src.GetID()

use:

   m_nID = src.m_nID

or whatever.  (There is no violation of encapsulation since you are in the same class).

Well that took care of the vector's complaints, but I still san't compile because I get: "cannot convert 'this' pointer from 'const class CMyClass' to 'class MyClass &" whenever I try to access the public methods of the src parameter.
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks alot.
That last suggestion hit the spot.
I should say I simply did not know that there is a difference between
const int a()
and
const int a() const
....
Mind elaborating on that a bit?
Zoppo, to declare the argument to the copy constructor:

 CMyClass const& src

makes no difference, the other form:

const CMyClass& src

means the same and is a lot more common in use.  The problem is that a non-const method is being called.  If you change your assignment operator to:
 
  if ( this != &src )
   m_nID = src.GetID();
  return (*this);

you will get the same problem.

It can be fixed by defining GetID as:

int GetID() const { return m_nID; };

or by writing it as you had it originally.

 

Just to keep the record straight, I did not answer the question.  I didn't think I deserved the points.  AssafLavie, accepted my comment as an answer.

>> I should say I simply did not know that
>> there is a difference between
>> const int a()
>> and
>> const int a() const

>> Mind elaborating on that a bit?

The first function returns a constant int, that is an int that can't e changed.  (Actually the value it returns could not be changed for other reasons anyways, so the constant is redundant.)

The send function is a a syntax error, unless it is a member function.  Only a member function can be declared with that "const" at the end.  This indicates that the member function treats the object that it works on as constant. So the function cannot change any of its data members  (unless they are mutable) and cannot call any other member functions that might change data members (other non-constant functions. )

for example

class X
{
  int i;
public:
   NonConstFun(int j)
   {
        i = j; // Okay, not constant.
   };
   ConstFun(int j) const
   {
        i = j; // ERROR.  can't change data of constant object.
       NonConstFun(j); // ERROR can't call non-constant member.
   };
};  
Note that this is a very basic element of C++'s OOP design.  If you don't know this, you probably don't know a lot of other basic things too--and that can be dangerous.  You probalby should invest in some basic C++ texts.  (Usually more than one.)