C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 06-12-2009, 11:48 AM   #1
Registered User
 
Join Date: Jan 2008
Posts: 64
Linker errors

I have a header file which contains the class with only function declarations. I then define the function in a separate cpp file. However, I get linker errors when I do this. If I define the function in the header file (but outside the class) I don't get linker errors. Why would it matter whether the function was defined inside the header or cpp file?

The function insertVertex is giving me problems.

GraphEdgeList.h
Code:
#ifndef GRAPHEDGELIST_H
#define GRAPHEDGELIST_H

#include <vector>
#include <list>

template <typename Object>
class Vertex {
private:
    template <typename> friend class GraphEdgeList;
    Object o;
    int undirectedDegree;
    int inDegree;
    int outDegree;
public:
    Vertex(const Object& oo = Object()) : o(oo), undirectedDegree(0),
        inDegree(0), outDegree(0)
    {
    }
    const Object& element() const {
        return o;
    }
    void element(const Object& oo) {
        o = oo;
    }
};

template <typename Object>
class Edge {
private:
    template <typename> friend class GraphEdgeList;
    typedef Vertex<Object> Vertex;
    Object o;
    Vertex* origin;
    Vertex* destination;
    bool isDirected;
public:
    Edge(const Object& oo = Object(), Vertex* org = NULL, Vertex* dst = NULL,
        bool directed = false)
        : o(oo), origin(org), destination(dst), isDirected(directed)
    {
    }
    const Object& element() const {
        return o;
    }
    void element(const Object& oo) {
        o = oo;
    }
};

/*
 * A graph represented by an edge list
 */
template <typename Object>
class GraphEdgeList {
    typedef Vertex<Object> Vertex;
    typedef Edge<Object> Edge;
    std::list<Vertex> V;
    std::list<Edge> E;
public:
    Vertex& insertVertex(const Object& o);
};

#ifdef DEFINEINHEADER

template <class Object>
typename GraphEdgeList<Object>::Vertex&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    typedef typename GraphEdgeList<Object>::Vertex Vertex;
    V.push_back(Vertex(o));
    return V.back();
}

#endif

#endif
GraphEdgeList.cpp
Code:
#include "GraphEdgeList.h"

#ifdef DEFINEINCPP

template <class Object>
typename GraphEdgeList<Object>::Vertex&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    typedef typename GraphEdgeList<Object>::Vertex Vertex;
    V.push_back(Vertex(o));
    return V.back();
}

#endif
main.cpp
Code:
#define DEFINEINCPP // this gives linker errors
//#define DEFINEINHEADER // this works
#include "GraphEdgeList.h"
#include <iostream>
#include <utility>
#include <string>

int main() {
    GraphEdgeList<std::string> g;
    g.insertVertex("SFO");
}
jw232 is offline   Reply With Quote
Old 06-12-2009, 11:54 AM   #2
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,368
You might want to read: Why can't I separate the definition of my templates class from it's declaration and put it inside a .cpp file?
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 06-12-2009, 12:38 PM   #3
Registered User
 
Join Date: Jan 2008
Posts: 64
From what I read, I just have to add another line to the cpp file. However, I'm still getting linker errors. What am I doing wrong?

Code:
#include "GraphEdgeList.h"

#ifdef DEFINEINCPP

template <class Object>
typename GraphEdgeList<Object>::Vertex&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    typedef typename GraphEdgeList<Object>::Vertex Vertex;
    V.push_back(Vertex(o));
    return V.back();
}

template class GraphEdgeList<std::string>; // added this line

#endif
jw232 is offline   Reply With Quote
Old 06-12-2009, 12:56 PM   #4
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
You have to add
Code:
#define DEFINEINCPP
into GraphEdgeList.cpp as well, otherwise it won't be defined. Of course, this is duplication of code, so I'd suggest adding the DEFINEIN* to another .h file which you then include in GraphEdgeList.h. That should solve the problem.

Also, by the way, I had compiler errors when compiling your code with g++ 4.3 and g++ 4.4. It doesn't like you doing things like this:
Code:
typedef Vertex<Object> Vertex;
Erros:
Code:
GraphEdgeList.h:56: error: declaration of ‘typedef class Vertex<Object> GraphEdgeList<Object>::Vertex’
GraphEdgeList.h:8: error: changes meaning of ‘Vertex’ from ‘class Vertex<Object>’
If I were you I'd pick a different name.

[edit] In case you're interested, here's the code I got to compile with g++ 4.3.
Code:
$ for file in *.cpp *.h; do echo === $file; cat $file; done
=== GraphEdgeList.cpp
#define DEFINEINCPP // this gives linker errors
#include "GraphEdgeList.h"

#ifdef DEFINEINCPP

template <class Object>
typename GraphEdgeList<Object>::Vertex_&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    //typedef typename GraphEdgeList<Object>::Vertex Vertex;
    V.push_back(Vertex_(o));
    return V.back();
}

#include <string>

template class GraphEdgeList<std::string>; // added this line

#endif
=== main.cpp
#define DEFINEINCPP // this gives linker errors
//#define DEFINEINHEADER // this works
#include "GraphEdgeList.h"
#include <iostream>
#include <utility>
#include <string>

int main() {
    GraphEdgeList<std::string> g;
    g.insertVertex("SFO");
}
=== GraphEdgeList.h
#ifndef GRAPHEDGELIST_H
#define GRAPHEDGELIST_H

#include <vector>
#include <list>

template <typename Object>
class Vertex {
private:
    template <typename> friend class GraphEdgeList;
    Object o;
    int undirectedDegree;
    int inDegree;
    int outDegree;
public:
    Vertex(const Object& oo = Object()) : o(oo), undirectedDegree(0),
        inDegree(0), outDegree(0)
    {
    }
    const Object& element() const {
        return o;
    }
    void element(const Object& oo) {
        o = oo;
    }
};

template <typename Object>
class Edge {
private:
    template <typename> friend class GraphEdgeList;
    typedef Vertex<Object> Vertex_;
    Object o;
    Vertex_* origin;
    Vertex_* destination;
    bool isDirected;
public:
    Edge(const Object& oo = Object(), Vertex_* org = NULL, Vertex_* dst = NULL,
        bool directed = false)
        : o(oo), origin(org), destination(dst), isDirected(directed)
    {
    }
    const Object& element() const {
        return o;
    }
    void element(const Object& oo) {
        o = oo;
    }
};

/*
 * A graph represented by an edge list
 */
template <typename Object>
class GraphEdgeList {
    typedef Vertex<Object> Vertex_;
    typedef Edge<Object> Edge_;
    std::list<Vertex_> V;
    std::list<Edge_> E;
public:
    Vertex_& insertVertex(const Object& o);
};

#ifdef DEFINEINHEADER

template <class Object>
typename GraphEdgeList<Object>::Vertex&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    //typedef typename GraphEdgeList<Object>::Vertex Vertex_;
    V.push_back(Vertex(o));
    return V.back();
}

#endif

#endif
$
Notice the #include <string> and the typedefs changed to Vertex_ etc. [/edit]
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort

Last edited by dwks; 06-12-2009 at 01:01 PM.
dwks is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Linker errors in VC++ 2005 C+/- C++ Programming 0 05-18-2007 07:42 AM
Sneaky little linker errors... Tozar C++ Programming 8 10-25-2006 05:40 AM
Linker errors when compiling The Wazaa C++ Programming 4 10-07-2006 12:55 PM
Linker errors with Visual C++ codegirl C++ Programming 4 09-11-2003 09:20 AM
MSVis-Studio C++ libraries and linker errors kellydj Windows Programming 10 03-12-2002 02:03 PM


All times are GMT -6. The time now is 01:48 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

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