templates and class inheritance

Hi all!

I'm new to this forum and I would say hello to everyone! Sorry for my english 'cause I'm Italian and something could has mistakes or errors.

I generally code in Java and I need to write something in C++ (I had previous experience but not too deep), that is a simple class that acts as a wrapper for another library. This library has a method addTerm() that adds a term to the object tree. Because each one can use a base type of their own I used templates and I also wrote a specialization of it to do some tests.
Anyway here is the base class/template

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
template <typename T>
class ITerm
{
public:
        ITerm(T value) : val(value)
        {
        }    
        
	virtual ~ITerm() {};
		
        inline int getVarNum() {
            return size;  
        }
        
        inline void setValue(T value) {
             val = value;
        }
        
        inline T getValue() {
             return val;
        }
        
    public:
        virtual bool getIthVar(int idx) = 0;
        
    private:
        static const size_t size = sizeof(T)*8;
        T val;
};


as you can see each one would use the type of their own and need only to supply the implemetation of the pure virtual function getIthVar. So I create a concrete implementation, here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

#include "iterm.h"

class UIntVar :
	public ITerm<unsigned int>
{
public:
	// class constructor
	UIntVar(unsigned int value) : ITerm<unsigned int>(value) {
        }
        
	// class destructor
	~UIntVar() {
        }
        
        bool getIthVar(int idx) {
             return (getValue() & (1<<idx)) ? true : false;
        }
};


I used unsigned integer as type but someone could use strings and access each char in the getIthVar and test if is "1" or "0" and return true of false.
I use this class in the main function like this:

1
2
3
4
5
6
7
8
9
10
        // The library
        BddWrapper wrap;
  
	UIntVar var(0);
	for(int i=0;i<10;i++) 
	{
		var.setValue(i);     
		wrap.addTerm(var); // <-- here comes the error
	}


The BddWrapper is defined as:

1
2
3
4
5
6
7
8
9
10
11
12
13
class BddWrapper
{
public:
	BddWrapper();
	BddWrapper(int varNum);
	~BddWrapper();
	template <typename T> bool addTerm(ITerm<T>& term);

private:
	int varNum;
	DdManager* manager;     
        DdNode* bdd; 
};


Everyhing compiles fine (Visual Studio 2010) but honestly I don't know if the definition of member function

 
template <typename T> bool addTerm(ITerm<T>& term);


is right or not. I want to have the base templated class as argument type so I can pass to it any kind of concrete implemetation I want but it fails to link with this message:


error LNK2019: unresolved external symbol "public: bool __thiscall BddWrapper::addTerm<unsigned int>(class ITerm<unsigned int> &)" (??$addTerm@I@BddWrapper@@QAE_NAAV?$ITerm@I@@@Z) referenced in function _wmain


Everything compiles fine if I comment the line pointed in the main function.

Sorry if I was so long but hope I gave everything to find a solution.
I don't know if this has a design error more than coding one.

Moreover if anyone has suggestion, code tips or anything is a good programming practice it would be very appreciated!! (I haven't code in C++ for years!)

If you need more infos, don't hesitate to ask!

Thank you so much!!

Bye!
All of you ITerm's are distinct types, with no static relationship between them at all. And because getIthVar is pure virtual, these classes cannot be instantiated.

The derived classes like UIntVar, don't actually add anything other than to implement getIthVar, which you could have done directly in ITerm.

I believe you're implementing a polymorphic collection that can hold any type. So, you should have a parent object, say CollectionBase, and make the container hold CollectionBase*.

Given that you want to hold any kind of object, does it really make sense for the collection to hold things that must have a getIthVar member? What's does getIthVar mean if T is a BankAccount?
Hi, thank you for you reply!

I designed ITerm as an abstract wrapper for any type. Like an adapter.

Well actually getIthVar cannot be implemented directly into ITerm (as I designed) because for each possible type (in reality not too many types) you should supply only the access method to its internal structure. Everyhing else (even if it's really simple) remains the same. You just have to construct one object and change its value over time (with ITerm::setValue), supply it to BddWrapper::addTerm and this method will inspect each var in the object (iterate from 0 to numVar-1 to read each bit) and construct another object (a Node for the BDD) and put into the original library structure. My classes act just as a transformation method. Hope I was clear enough.

For example, for the UIntVar that uses unsigned int as underlying storage I implemented it as bit mask&shifting but I could have used strings doing something like this: s[idx]=="1" ? true : false; or an unsigned long or a std::vector of bits...
It's not a real collection it is only a wrapper for a specific type that should be handled by my library always in the same manner. I thought about template specialization but I had to reimplement everything for each specialization (correct me if I'm wrong).

The only problem that I have is to find the correct signature that BddWrapper::addTerm should have to support (read link) this kind of design flawlessly...

I dont' want to build any collection...

Thank you!
Topic archived. No new replies allowed.