Ask for help: Is it correct to use template in this way?

Hi rooters,

    :cry: I made a class then complied and did a test. But ROOT exited when I call the constuctor. I want to know why?

//----------------- Node.h------------------------------
#ifndef _NODE_H
#define _NODE_H

#include “TObject.h”

template
class Node : public TObject
{
private:
T *fCont;
Node *fLeft;
Node *fRight;
void SetLeft(Node *left) { fLeft=left;}
void SetRight(Node *right) { fRight=right;}

public:
Node();

T *GetCont(){return fCont;}
Node *GetLeft(){ return fLeft;}
Node *GetRight() {return fRight;}

ClassDef(Node,0)

};

#endif

//------------------Node.cxx---------------------

#include “Node.h”

templateClassImp(Node);

template
Node::Node()
{}

//-----------------NodeLinkDef.h---------------

#ifdef CINT
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class Node+;

#endif
//---------------------Makefile----------------

ARCH = linux

filename =Node

CXX =
ObjSuf = o
SrcSuf = cxx
ExeSuf =
DllSuf = so
OutPutOpt = -o

ROOTCFLAGS := $(shell root-config --cflags)
ROOTLIBS := $(shell root-config --libs)
ROOTGLIBS := $(shell root-config --glibs)

ifeq ($(ARCH),linux)

Linux with egcs, gcc 2.9x, gcc 3.x (>= RedHat 5.2)

CXX = /usr/bin/g++
CXXFLAGS = -O -Wall -fPIC
LD = /usr/bin/g++
LDFLAGS = -O
SOFLAGS = -shared
endif

ifeq ($(CXX),)
$(error $(ARCH) invalid architecture)
endif

INCLUDES = -I/home/luxg/source/include -I/hermes/pro/writeDST/ddl
CXXFLAGS += $(ROOTCFLAGS)
LIBS = $(ROOTLIBS) $(SYSLIBS) -L/home/luxg/source/lib
GLIBS = $(ROOTGLIBS) $(SYSLIBS)

#------------------------------------------------------------------------------

PARTICLEO = $(filename).$(ObjSuf) $(filename)Dict.$(ObjSuf)
PARTICLES = $(filename).$(SrcSuf) $(filename)Dict.$(SrcSuf)
PARTICLESO = lib$(filename).$(DllSuf)
PARTICLE = $(filename)$(ExeSuf)
PARTICLELIB = $(PARTICLESO)

OBJS = $(PARTICLEO)
PROGRAMS = $(PARTICLE)

#------------------------------------------------------------------------------

.SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)
.PHONY: Aclock Hello Tetris

$(PARTICLESO): $(PARTICLEO)
$(LD) $(SOFLAGS) $(PARTICLEO) $(OutPutOpt) $(PARTICLESO)
@echo “$@ Successfully Made!!”

clean:
@rm -f $(OBJS) core

distclean: clean
@rm -f $(PROGRAMS) $(PARTICLESO) $(PARTICLELIB) Dict. *.def *.exp
*.root *.ps *.so .def so_locations
@rm -rf cxx_repository

.SUFFIXES: .$(SrcSuf)

$(filename).$(ObjSuf): $(filename).h

$(filename)Dict.$(SrcSuf): $(filename).h $(filename)LinkDef.h
@echo “Generating dictionary $@…”
@rootcint -f $@ -c $^

.$(SrcSuf).$(ObjSuf):
$(CXX) $(CXXFLAGS) -c $<

//------------------------Make----------------
$ make
/usr/bin/g++ -O -Wall -fPIC -pthread -I/home/luxg/root/root-4.04.02g/include -c Node.cxx
Generating dictionary NodeDict.cxx…
/usr/bin/g++ -O -Wall -fPIC -pthread -I/home/luxg/root/root-4.04.02g/include -c NodeDict.cxx
/usr/bin/g++ -shared Node.o NodeDict.o -o libNode.so
libNode.so Successfully Made!!

//-----------------testnode.C-----------------

#includelibNode.so

typedef Node INode;
testnode()
{

INode a;
}

//-------------------test in ROOT-----------------

$ root
root [0] .x testnode.C
/home/luxg/root/root-4.04.02g/bin/root.exe: error while loading shared libraries: /home/luxg/source/Hermes/decompose/mail/./libNode.so: undefined symbol: __t4Node1Zi

Can somebody help me?

Hi,

You need to the implementation of the constructor into the header file. I.e

should be in Node.h

Cheers,
Philippe

Hi Philippe,

  Thanks very much!

But it seems that I have to change the code into:
//----------------------------------------
template
inline Node::Node()
{}

other wise, if the code is :
//-----------------------------------------
inline template Node::Node() //L29
{}

an error occurs when I made the library:
//*****************************
$ make
/usr/bin/g++ -O -Wall -fPIC -pthread -I/home/luxg/root/root-4.04.02g/include -c Node.cxx
In file included from Node.cxx:1:
Node.h:29: parse error before `<'
Node.cxx:4: definition provided for explicit instantiation
/home/luxg/root/root-4.04.02g/include/TBuffer.h:63: definition provided for explicit instantiation
/home/luxg/root/root-4.04.02g/include/TBuffer.h:63: non-template used as template
/home/luxg/root/root-4.04.02g/include/TBuffer.h:63: confused by earlier errors, bailing out
make: *** [Node.o] Error 1

Cheers.
Xian-Guo Lu

Yes you are right (my mistake :frowning:).

Cheers,
Philippe