views:

314

answers:

3

Hi. I'm working on a project for school with data structures in Visual C++. I got my code compiling just fine earlier today, and took it home and it no longer works. Both machines I've been working on use Visual Studio 2008. Here's the text of the error.

I'm not sure if this might have anything to do with it, but my program has 3 main classes: AVL, which inherits from BST, which inherits from SearchableADT. These are templated classes.

BST.obj : error LNK2005: "public: __thiscall BST,class std::allocator > >::BST,class std::allocator > >(void)" (??0?$BST@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@XZ) already defined in AVL.obj

I'm at a complete loss for what to do. I've poked around on a few forums, looked at the MSDN page, and nothing's been able to fix it.

One thing I noticed mentioned on a site that I forgot was to have #ifndef/#define for my AVL. I created a fresh project and copy and pasted all my code in with this addition, and I'm still getting the same error though. I've looked over my code to verify that I'm not doing multiple includes of libraries. I'm at a loss for what to do from here though.

Thank you for any help you can provide, and sorry in advance if I left out something important.

Edit: I'm not sure 100% by what you mean with inline, trying to do some looking now. I do have a seperate cpp where I define the actual functions. Would the inline thing in Greg's answer still apply?

MSN, I'm afraid I didn't understand your answer. As for multiple copies of the default constructor, I do have

BST<int>::BST()
{
    root = new Node<int>;
}

BST<string>::BST()
{
root = new Node<string>;
}

I'm not sure if that's what you were talking about, or if that might be the issue. My header file only has BST();, nothing for the int or string template. I have those definitions in my cpp because my instructor said they were necessary for the templated class.

Thank you very much

A: 

Declare BST::BST(void) inline and make sure you didn't violate the One Definition Rule and have different implementations of BST::BST(void) depending on some other preprocessor fun.

MSN
+1  A: 

It sounds like you might have defined a method in a header file in a non-inline way. For example, having the following in a header file might cause such a problem:

template <class T> class Foo {
    void bar();
};

template <class T> void Foo<T>::bar()
{
    // ...
}

With that in the header file, then including it into two different modules will provide two different definitions of the same Foo<T>::bar() function, with the resulting error that you got. One solution is to declare the function inline:

template <class T> class Foo {
    void bar() {
        // ...
    }
}
Greg Hewgill
+1  A: 

You don't define a separate constructor for each instantiated type of your template. You only need one constructor, for BST. You can create an instance of the node class by using the template parameter:

root = new Node<T>();
Andy