0

As making a small project for my college work, i thought to work on c++.

My project has many *.h and corresponding *.cpp files.

Then i created a main file that has the main function. I included all the header files that i required in main. but it showed [Linker error] undefined reference to `Class_Name::Class_Constructor()' and also for other functions.

Then i replaced header files with source cpp files and it worked. Now i thought that it should be other way round. and cannot explain why it is happening. since we generally include header files only and that works. May be generally we require only declarations and now we require definitions in main. Am i right ?

// please note that the following code is working but i want to include header files not source files.

Here is the code: // My Main file

#include "MicroProcessor.cpp"

#include "Register/Register.cpp"

#include "Register/RegistersName.cpp"


#include <iostream>

using namespace std;

int main(){
MicroProcessor<REG_SIZE> mp;
mp.move(RegistersName::AX , RegistersName::BX);
cout << "hello";
return 0;
}

#ifndef MICROPROCESSOR_H
#define MICROPROCESSOR_H

#include "Register/RegistersName.h"
#include "Register/Register.h"
#include "Register/RegisterConstants.h"
using namespace std;

template<int regSize>
class MicroProcessor
{
private:
    Register<REG_SIZE> *registers;
    Register<FLAG_SIZE> *flags;
public:
    MicroProcessor();

    ~MicroProcessor();

    void move(RegistersName destination, RegistersName source);

};

#endif // MICROPROCESSOR_H

#ifndef REGISTER_H
#define REGISTER_H

/* This is the Register Class. */

#include <bitset>
#include "RegisterConstants.h"
using namespace std;

template <int regSize=REG_SIZE>
class Register
{
private:
       bitset<regSize> reg ;
   int carry ;
   int a;
public:
   // Constructor
   Register();

   // parameterized constructor
   // @param:
   // 
   Register(const string &binary);

   // destructor
   // get the bitset<> reg bit number position
   int get(int position)const;

   //reset the bit at position
   void reset(int position);

   //reset the bit at position
   void set(int position);


   // move the value of a register into another
   Register move(const Register &source, int startIndex=0, int len=REG_SIZE);

   // display the contents of the register but from last to first 
   // because lowest bit is stimulated as 0th index of register in memory.  
   void display();


   // return the size of the register bitset<> reg
   int size()const;

   // add two registers result = this + other, return result
   // but should be this = this + other, return this
   // this is more like operator +()
   Register add(const Register &other);

   // adds two registers and returns the sum of the registers without modifying any of them 
   Register operator+(const Register &other);     

   // add the bits of the register
   int addBits(int bit1, int bit2, int cary);

   // is carry is set after the operations
   bool isCarry();
};

#endif // REGISTER_H

#ifndef REGISTER_CPP
#define REGISTER_CPP

#include <iostream>

using namespace std;

#include "Register.h"

#include <bitset>

// Constructor
template<int regSize> Register<regSize> :: Register(){
carry = 0;       
}

/* other code */

#endif // REGISTER_CPP

CC = g++

HEADER =  Register/Register.h Register/RegistersName.h MicroProcessor.h 

SRC = Register/Register.cpp Register/RegistersName.cpp MicroProcessorTest.cpp 
MicroProcessor.cpp 

OUTPUT = out_executable.x

OBJS =  MicroProcessorTest.o MicroProcessor.o Register/Register.o       
Register/RegistersName.o 

.cpp.o: 
$(CC) -c $< 

MicroProcessorTest.o: MicroProcessorTest.cpp MicroProcessor.h Register/Register.h 
Register/RegistersName.h

MicroProcessor.o: MicroProcessor.cpp Register/Register.h Register/RegistersName.h

Register/Register.o: Register/Register.cpp Register/RegistersName.h

Register/RegistersName.o: Register/RegistersName.cpp

build:  $(OBJS)

$(CC) -o $(OUTPUT) $(OBJS)

./$(OUTPUT)

clean: -rm *.x *.o cd Register -rm *.x *.o

rebuild: clean build

----------

well now the problem is:

well the template parameter of mine is always int .. so should that means that i should do something like template_Class<16> ; in cpp file.

well if you see my code. can i get regSize at run time because that what i want to get different size of registers in my RegisterClass that has a varible of type bitset.

if i can only do that at compile time than i should be doing #define regSize 16 rather than making a template.

or should i put all the code in the template file only

Ashish Negi
  • 5,193
  • 8
  • 51
  • 95
  • 1
    Can you show us some code so we might see the reason for the error? – Norbert Jul 30 '11 at 06:09
  • you are probably not compiling other cpp files with your main. Include them in your project – Gasim Jul 30 '11 at 06:15
  • @Mihai i am compiling it using makefile but as a newbie not sure of wheter it could be right. does orddring of " g++ -o output containg_main.o first_file.o second_file.o" is different from "g++ -o output first_file.o containg_main.o second.o" – Ashish Negi Jul 30 '11 at 07:08
  • How did you **link** it? – Soren Jul 30 '11 at 07:11
  • i first used makefile bt wen it showed errors i went to windows and used dev_cpp . – Ashish Negi Jul 30 '11 at 07:22
  • possible duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Yakov Galka Jul 30 '11 at 07:53
  • well the template parameter of mine is always int .. so should that means that i should do something like template_Class<16> ; in cpp file – Ashish Negi Jul 30 '11 at 08:32
  • well if you see my code. can i get regSize at run time because that what i want to get different size of registers in my RegisterClass that has **bitset**. if i can only do that at compile time than i should be doing #define regSize 16 rather than making a tmplate. – Ashish Negi Jul 30 '11 at 08:41

3 Answers3

2

You should only include header files inside your source code. However, you must compile and link all .cpp files in your project. If you don't, the compiler/linker won't be able to find the implementation for the functions defined in the headers.


After seeing the source code, I think the problem is in the makefile. Change this:

.cpp.o: 
$(CC) -c $< 

to:

.o: 
$(CC) -c $< 
nmat
  • 7,430
  • 6
  • 30
  • 43
  • i have separetly compiled all cpp files and when i use g++ -o all_files.o ... i get multiple declaration errors when i include cpp files in my main file. i am using makefile. is there error in cpp file – Ashish Negi Jul 30 '11 at 07:14
  • Could you post the compiler commands or the Makefile? It would help – nmat Jul 30 '11 at 07:17
  • i compiled it in dev_cpp also in windows . with header files included in main.cpp it also gave the errors. – Ashish Negi Jul 30 '11 at 07:21
  • I think you have a problem with your makefile. Check my edit. – nmat Jul 30 '11 at 07:27
1

Which compiler/IDE you are using to build the code? Check the source file having Class_Name::Class_Constructor and add the same source file in building process.

Ajay
  • 18,086
  • 12
  • 59
  • 105
1
  • If "main.cpp" is the ONLY source file you compile, then this should work fine:
    // Effectively, you've created one, big, happy source file for the entire project
    #include "MicroProcessor.cpp"
    #include "Register/Register.cpp"
    #include "Register/RegistersName.cpp"
    #include 

    using namespace std;

    int main(){
      MicroProcessor mp;
      mp.move(RegistersName::AX , RegistersName::BX);
      cout 
  • If, on the other hand, you compile "main.o" (with #included' modules) AND "Microprocessor.cpp" AND ..., then you should "duplicate definition" link errors when you create the .exe

  • My guess is that your build tool FAILED to find (or simply failed to build) the other modules, hence the "undefined reference" link error. And hence the lack of conflict from your "#includes".

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • you are right. but this is compiling good . but if i use headr file then i gives undeclared references errors – Ashish Negi Jul 30 '11 at 07:26
  • and also doing it like this gives multiple declaration errors. – Ashish Negi Jul 30 '11 at 07:27
  • Per above: "My guess is that your build tool FAILED to find (or simply failed to build) the other modules, hence the "undefined reference" link error." – paulsm4 Jul 31 '11 at 02:54