How to access derived class members from virtual base class object?

I'm writing a program that uses a base class with a constructor that takes a bool variable. If the bool is true then it will create a dynamic array, if false it will create a linked list. So far I've just written the implementation for the dynamic array derived class, but I can't seem to figure out how I should make an object correctly use the bag constructor to create a DAbag object. Is what I have here correct? I have the Source.cpp, which is where I'll test the classes, bagb.cpp, which has the derived classes, and bagb.h, which has the base class.
Source.cpp :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "bagb.h"
#include <iostream>

using namespace std;
using namespace bag_hierarchy;


int main()
{
	bool pass = true;
	bag daptr(pass);
	daptr = daptr->create(true);
	daptr->insert(42);
	daptr->insert(36);
}

bagb.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifndef BAG_BASE_H
#define BAG_BASE_H
#include <cstdlib>  // Provides size_t

namespace bag_hierarchy
{
    class bag
    {
    public:
        // TYPEDEFS and MEMBER CONSTANTS
        typedef int value_type;
        typedef std::size_t size_type;

        //static const size_type DEFAULT_CAPACITY = 30;        
        // CONSTRUCTORS and DESTRUCTOR
        //bag(size_type initial_capacity = DEFAULT_CAPACITY);
        //bag(const bag& source);
        //factory method to construct derived class objects

		bag()
		{

		}

		bag(bool daORll)
		{
			if (daORll)
			{
				DAbag();
			}
		}

		static bag* create(bool daORll)
		{
			if (daORll)
			{
				DAbag *daptr;
				return daptr;
			}
			else
			{
				LLbag *llptr;
				return llptr;
			}
		}

	  /*bag(bool input)
		{
			value = input;
			create(value);
		}*/
        //mimic a virtual copy constructor
        virtual bag* clone(const bag& source) = 0;
	//virtual destructor
		virtual ~bag() {};
        // MODIFICATION MEMBER FUNCTIONS
        //void reserve(size_type new_capacity);
        virtual bool erase_one(const value_type& target) = 0; //DA
        virtual size_type erase(const value_type& target) = 0; //DA
        virtual void insert(const value_type& entry) = 0;  //DA
        //virtual void operator +=(const bag& addend) = 0;
        virtual void operator =(const bag& source) = 0; //DA
        // CONSTANT MEMBER FUNCTIONS
        virtual size_type size( ) const = 0;  //DA
        virtual size_type count(const value_type& target) const = 0; //DA
    private:
    };

    // NONMEMBER FUNCTIONS for the bag class
    bag operator +(const bag& b1, const bag& b2);
}

#endif 

bagb.cpp :
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "bagb.h"
#include <iostream>

using namespace std;

namespace bag_hierarchy
{

	class DAbag : public bag
	{
	public:
		size_t const capacity = 50;
		size_t used = 0;
		bool* in_use;
		value_type* data;

		DAbag()
		{
			in_use = new bool[capacity];
			data = new value_type[capacity];
		}

		void insert(const value_type& entry)
		{
			if (size() < capacity)//checks to make sure that we aren't about to go over CAPACITY
			{

				for (size_t loop = 0; loop < capacity; loop++)//checks each member of the in_use array
				{
					//cout <<  "/ " << in_use[loop] << "/\n";
					if (!in_use[loop])//checks to see if the current slot is empty
					{
						in_use[loop] = true;//sets the loop'th member of the in_use array to true
						++used;//adds one item to amounts of items in bag 
						data[loop] = entry;//inserts the item into the currently empty slot
						//if (loop == 0)
						//{
						//	return loop;   COMMENTED OUT UNTIL I KNOW RECEIPTS ARE NEEDED
						//}
						//else
						//{
						//	return loop - 1;//returns the receipt
						//}

						//also check out this CLEAN concatenation
					}
				}

			}
			else
			{
				cout << "Bag is Full!\n";
			}
			return;
		}

		size_type size() const{ return used; } 

		bool erase_one(const value_type& target)
		{
			if (target <= capacity)
			{
				in_use[target] = false;
				data[target] = 0;
				used--;
				return true;
			}
			return false;
		}

		size_type erase(const value_type& target)
		{
			for (int i = 0; i < capacity; i++)
			{
				if (in_use[i] == true)
				{
					if (data[i] == target)
					{
						in_use[i] = false;
						data[i] = 0;
						used--;
						
					}
				}
			}
		}

		size_type count(const value_type& target) const
		{
			size_type occur;
			occur = 0;

			for (int i = 0; i < used; i++)
			{
				if (in_use[i] == true)
				{
					if (data[i] == target)
					{
						occur += 1;
					}
				}
			}

			return occur;

		}

		void operator =(const bag& source)
		{
			
			used = source.
			for (int i = 0; i < capacity; i++)
			{
				in_use[i] = source.in_use[i];
				data[i] = source.data[i];
			}
			
		}

		bag* clone(const bag& source)
		{
			bag* cloneHold;
			cloneHold = cloneHold->create(true);
			cloneHold->used = source.used;
			for (int i = 0; i < capacity; i++)
			{
				cloneHold->in_use[i] = source.in_use[i];
				cloneHold->data[i] = source.data[i];
			}

			return cloneHold;
		}

		void display()
		{
			cout << "These are the contents of this object: " << used << " " << capacity << "\n";
			for (int i = 0; i < capacity; i++)
			{
				cout << i << " : " << in_use[i] << " : " << data[i] << "\n";
			}
		}
	};
Hello Toasthat

Why do you think that you need a bool for the constructor?

You already have the bool in your create() function where you actually make the decision which type of object to create. Thus, I would think the constructor with the bool is unnecessary.
You need a better understanding of pointers.
1
2
	bag daptr(pass);
	daptr = daptr->create(true);
-> is for pointers. Use . instead.
1
2
DAbag *daptr;
return daptr;

This returns an uninitialized pointer.

Your create() method should allocate the bag on the heap:

1
2
3
4
5
6
7
static bag* create(bool daORll)
{
	if (daORll) {
		return new DAbag;
	} else {
		return new LLbag;
}


Because the method is static, you don't actually need an instance to call it, so in main() you can do:
bag *daptr = Bag::create(true);


Some other comments:
1
2
3
		bool erase_one(const value_type& target)
		{
			if (target <= capacity)

Since target is a value, it makes no sense to compare it to capacity. I'd implement erase() and erase_one using a private method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private:
		// Erase elements equal to "target". This erases all matching items
		// or just one, depending on "justOne"
		size_type doErase(const value_type& target, bool justOne)
		{
			size_t result = 0;
			for (int i = 0; i < capacity; i++) {
				if (in_use[i] == true && data[i] == target) {
					in_use[i] = false;
					data[i] = 0;
					used--;
					++result;
					if (justOne) break;					
				}
			}
			return result;
		}
public:
		size_t erase(const value_type &target) { return doErase(target, false); }
		bool erase_one(const value_type target) {return doErase(target, true); }

void operator =(const bag& source)
Since source could be an LLbag, you need to implement this using only the public interface. Put another way LLbag might not have in_use and data members, so you can't use them.
Topic archived. No new replies allowed.