I am compiling my two .cpp files that are linked with header file. i am getting the error


~/...>g++ -o test.exe diamondtest.o main.o
Undefined first referenced
symbol in file
Diamond::Diamond(int) main.o
Diamond::Diamond(int, char) main.o
ld: fatal: Symbol referencing errors. No output written to test.exe
collect2: ld returned 1 exit status

It seems to be in the header file i think. Here are my codes

------diamond.h------
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

class Diamond
{
public:
        Diamond();
        Diamond(int size);
        Diamond(int size, char border);
        Diamond(int size, char border, char fill);

//functions
        double Area();
        int Perimeter() const;
        int GetSize() const;
        void Grow();
        void Shrink();
        void SetBorder(char border);
        void SetFill(char fill);
        void Draw();
        void Summary();



private:
int size; //if less than 1, size=1. if greater than 39, size=39
char fill; // fill is '*'
char border; // border is '#'
};
---main.o----
#include <iostream>
#include <iomanip>
#include "diamond.h"

using namespace std;

int main() 
{
  // set decimal outputs to 2 decimal places
  cout << setiosflags( ios::fixed | ios::showpoint )
	<< setprecision( 2 );

  // create some Diamonds
  Diamond d1( -5 ), d2( 7, '^' ), d3( 12, 'X', 'O' ), d4( 50 , '$' , 'o');
  // display original Diamonds
  cout << "d1 has size = " << d1.GetSize() << " units.\n";
  d1.Draw();
  cout << "\nd2 has size = " << d2.GetSize() << " units.\n";
  d2.Draw();
  cout << "\nd3 has size = " << d3.GetSize() << " units.\n";
  d3.Draw();
  cout << "\nd4 has size = " << d4.GetSize() << " units.\n";
  d4.Draw();
  cout << '\n';

  d1.Shrink(); // demonstrate shrink
  d2.Shrink();
  d3.Grow(); // and grow
  d4.Grow();
  cout << "d1 now has size = " << d1.GetSize() << " units.\n";
  cout << "d2 now has size = " << d2.GetSize() << " units.\n";
  cout << "d3 now has size = " << d3.GetSize() << " units.\n";
  cout << "d4 now has size = " << d4.GetSize() << " units.\n";

  // demonstrate perimeter
  cout << "d2 has perimeter = " << d2.Perimeter() << " units.\n"; 
  cout << "d3 has perimeter = " << d3.Perimeter() << " units.\n"; 
  // and area
  cout << "d2 has area = " << d2.Area() << " square units.\n\n"; 
  cout << "d3 has area = " << d3.Area() << " square units.\n\n"; 

  d1.Draw();
  d1.Grow();               // show that fill character
  cout << "d1 grows:\n";   // appears only when size
  d1.Draw();               // is at least 3
  d1.Grow();
  cout << "... and grows:\n";
  d1.Draw();
  cout << '\n';

  d1 = d2; // demonstrate the default overload of the
  // assignment operator
  cout << "d1 now has size = " << d1.GetSize() << " units.\n";
  d1.Draw(); 

  // demonstrate the changing of border and fill characters
  d2.SetBorder('@');
  d2.SetFill('-');
  cout << "d2 now looks like:\n";
  d2.Draw();
  cout << '\n';
  d2.SetBorder('\n');	 // illegal border
  d2.SetFill('\a');	 // illegal fill
  cout << "d2 now looks like:\n";
  d2.Draw();
  cout << '\n';

  cout << "\nHere is a summary on d3:\n"; // demonstrate summary
  d3.Summary();

  return 0;
}
-----Diamond.o---------
#include "diamond.h"

// definition of Member Functions for class Diamond
Diamond::Diamond(int side, char border = '#', char fill = '*')
{
   if (size < 1)        // if sideLength is less than 1
   {
           size = 1;
   }
   else if (size > 39)  // if sideLength is greater than 39
   {
           size = 39;
   }
   SetBorder(border);     // calls SetBorder function
   SetFill(fill);         // calls SetFill function

}

int Diamond::GetSize() const
{
        return size;        // returns length of a side
}

int Diamond::Perimeter() const
{
        return (size * 4);  // returns perimeter length
}

double Diamond::Area()
{
        double area = 0;
        double sideLength = 0;
        sideLength = size;       // creates a copy of size

        // find area of the diamond
        area = sqrt((sideLength * sideLength) - ((sideLength / 2) * (sideLength / 2)));
        area = 2 * (area * (sideLength / 2));
        return area;
}

void Diamond::Grow()
{
        size++;        // increases sideLength by 1
        if (size > 39) // checks if sideLength is greater than 39
       size++;        // increases sideLength by 1
        if (size > 39) // checks if sideLength is greater than 39
        {
                size = 39;
        }
}

void Diamond::Shrink()
{
        size--;        // decreases sideLength by 1
        if (size < 1)  // checks if sideLength is less than 1
        {
                size = 1;
        }
}
    
void Diamond::SetBorder(char border2)
{
        // checks if borderChar is not in range
        if ((border < 33) || (border > 126))
        {
                border = '#';
        }
}
 
void Diamond::SetFill(char fill2)
{
 
        // checks if fillChar is not in range
        if ((fill < 33) || (fill> 126))
        {
                fill = '*';
        }
}
        
void Diamond::Draw()
{
        int x, y;               // declare x and y as integers
        
        // prints top part of the diamond
        for (x = 1; x <= size; x++)
        {
                for (y = 1; y <= size - x; y++)
                {   
                        cout << " ";
                }
                cout << border;
                }
                cout << border;
                if (x > 2)
                {
                        for (y = 1; y <= x - 2; y++)
                        {
                                cout << " " << fill;
                        }
                        cout << " " << border;
                }
                else if (x == 2)
                {
                        cout << " " << border;
                }   
                cout << "\n";
        }
        
        // prints bottom part of the diamond
        for (x = size - 1; x >= 1; x--)
        {
                for (y = 1; y <= size - x; y++)
                {   
                        cout << " ";
                }
                cout << border;
                if (x > 2)
                {
                        for (y = 1; y <= x - 2; y++)
                        {
                                cout << " " << fill;
                        }
                        cout << " " << border;
                }
                else if (x == 2)
                {
                        cout << " " << border;
                }
                cout << "\n";
        }

}

void Diamond::Summary()
{
        // prints size of the diamonds side
        cout << "Size of diamond's side = " << size << " units.\n";
       cout << "Size of diamond's side = " << size << " units.\n";
                
        // prints the perimeter
        cout << "Perimeter of diamond = " << Perimeter() << " units.\n";
                        
        // returns area with 2 decimal integer
        cout << "Area of diamond = ";
        cout <<  setprecision(2) << setiosflags(ios::fixed) << Area();
        cout << " units.\n";
                 
        // Draws the actual diamond
        cout << "Diamond looks like:\n";
        Draw();
}

Ok, you have multiple problems.

1) Those are not .o files. They are .cpp files.
2) At line 87 in diamond.cpp, you have

for (y = 1; y <= size - x; y++)
                {
                        cout << " ";
                }
                cout << border;
                }

That is an extra }, it should be just:

for (y = 1; y <= size - x; y++)
                {
                        cout << " ";
                }

(you also have the same problem again later)

3) You don't have header guards:

#ifndef DIAMOND_H
#define DIAMOND_H

// your header

#endif

4) The real problem you were asking about:

You are indeed missing definitions for those constructors. Adding this to diamond.cpp lets it compile and link properly:

Diamond::Diamond(int)
{

}

Diamond::Diamond(int, char)
{

}

Good luck,

David

This article has been dead for over six months. Start a new discussion instead.