Two ?s, vector<char>::iterator init syntax and base class pointers

Hello,
I am having a couple of issues at the moment. I declared a vector (vector<char> str) and want an iterator to access it. A book and this site (http://www.cplusplus.com/reference/stl/vector/begin.html) say that this is the correct syntax:
1
2
3
4
5
6
#include <vector>

/* ... */

vector<char> str;
vector<char>::iterator loc;


And it gives this error:
error C2955: 'std::iterator' : use of class template requires template argument list
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xutility(688) : see declaration of 'std::iterator'

Second issue: base class pointers.

I have a bunch of derived classes, say the letters a through d derived from myClass (ex. class a : public myClass;).

Inside the base class, I want to declare a base class pointer (myClass *p), and allocate memory for a derived class.

Heres some code to illistrate my problem:

header1.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef HEADER1_H
#define HEADER1_H

// foward declaration
class a;
class b;
class c;
class d;

class myClass
{
    int test;
    myClass *p;
public:
    bool allocFunc(int test);
};

bool myClass::allocFunc(int test)
{
    switch(test)
    {
    case 1:
        try{
            p = new a;
        }catch(...){
	    return false;
	}
        break;
    case 2:
        try{
            p = new b;
        }catch(...){
	    return false;
	}
        break;
    case 3:
        try{
            p = new c;
        }catch(...){
	    return false;
	}
        break;
    case 4:
        try{
            p = new d;
        }catch(...){
	    return false;
	}
        break;
    }
}
#endif /* HEADER1_H */


header2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef HEADER2_H
#define HEADER2_H

// foward declaration
class myClass;

class a : public myClass
{
/* ... */
};

class d : public myClass
{
/* ... */
};

class c : public myClass
{
/* ... */
};

class d : public myClass
{
/* ... */
};
#endif /* HEADER2_H */


And with these I'm getting an error similar to:
error C2440: '=' : cannot convert from 'a *' to 'myClass *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Any ideas on these two errors? I can post some actual code I am using, but I thought it would be simpler to write some unobfuscated stuff. Let me know what you think,

enduser
Last edited on
1.) Yeah, I got that to compile fine...I don't see where the error would be coming from...

2.) Since p is a MyClass* you can't suddenly change it to a derived class pointer (a*)...I don't really see why you would want to do this anyway.
1) Either use std::vector<char> (note the std::) or use the std namespace.

2) Use the clone pattern instead.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class clonable {
   public:
      virtual clonable* clone() const = 0;
};

class myClass: public clonable {
   // Your stuff here
  public:
     virtual myClass* clone() const
        { return new myClass( *this ); }
};

class a: public myClass {
   // Your stuff here
  public:
     virtual a* clone() const
        { return new a( *this ); }
};
@firedraco: I want to create an instance of a derived class, but I want to decide which one at runtime. I figured because base class pointers can point to derived classes they should be able to allocate them, right?

@jsmith: Could you explain the syntax: ret-type funcName(param list) const? I haven't used that syntax before. Also, your code compiles fine, but why do use virtual functions, I thought they were used so you declare one in the base class and different types of it (without virtual keyword) in dervied-classes.

I'm gonna keep reading...

edit: I am using an ("using namespace std;") statement in the file using the vectors. the syntax that's causing the issue is: vector<char>::iterator it

enduser
Last edited on
The keyword const used in member function means that the function is not allowed to modify members of that class
@enduser000: Typically a base class knows nothing about its descendants, so the answer is no, not without some help. The clone pattern solves just that problem.

It is not necessary to redeclare the clone() method as virtual in the descendant classes since once the method is declared virtual in the base class, it is virtual in the derived classes. However it doesn't to do it either.
Okay... sorry to be so ignorant... but what I understand this clone class to do is:
1
2
3
4
class clonable {
   public:
      virtual clonable* clone() const = 0;
};

Create a class called clonable, set it's constructor to null

1
2
virtual myClass* clone() const
        { return new myClass( *this ); }

Create a derived class that allocates itself and returns the address.

But how would I use this if I decided at runtime I want a clonable object, and then, as a member of the object (probably private), an object of type 'a'. How could I choose this one class to allocate and not the others? Once again sorry for slowness, just don't get it,

enduser
The first code block is just declaring a pure virtual clone() method, making clonable an abstract base class. It has nothing to do with constructors.

Any class you want to be clonable should derive from clonable and implement the clone() method. The implementation of the method is essentially the same for every derived type; it simply returns a new copy-constructed instance of itself.

The clone pattern is typically used in the scenario where you have a function that receives as a parameter a pointer to a base class instance and you want to create a copy of the instance. In order to create a copy of a instance, you have to run the constructor. In order to run the constructor, you have to know the actual type of object passed in. The clone pattern is the only way to do that.

Here's a code example of how clonable would be used:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class clonable {
  public:
     virtual clonable* clone() const = 0;
};

class base : public clonable {
   public:
      void dup( const base& b )
         { my_copy = b.clone(); }
   private:
        base* my_copy;
};

class derived1 : public base {
   public:
       virtual derived1* clone() const
          { return new derived1( *this ); }
};

class derived 1a : public derived1 {
   public:
       virtual derived1a* clone() const
          { return new derived1a( *this ); }
};

class derived2 : public base {
   public:
      virtual derived2* clone() const
          { return new derived2( *this ); }
};

Ok... When I try to compile the code above I get:

cloneable.cpp
cloneable.cpp(9) : error C2440: '=' : cannot convert from 'clonable *' to 'base *'
Cast from base to derived requires dynamic_cast or static_cast

The reason I started this was so I could have class word (base), and then if I decided the word was a noun, I could assign the base class pointer in word an object of type noun. I tried this way, but still don't completely understand it, what do you gain by making the derived class constructors virtual? I've also tried foward declaration
(
1
2
class base;
class d1 : public base;
)
But that didn't do it ethier. What do you think?

enduser000
Last edited on
Topic archived. No new replies allowed.