3

and thank you for all help in advance. I am new to C/C++ and am teaching myself by throwing myself in the deep end. I am attempting to write a shared (static? not sure the difference) library and write a simple program to use said library. I am probably not doing this in the most efficient way (if it were Python, I'd be done with this project a week ago) but I am more concerned in knowing what and why I am doing things incorrectly. Again, thank you for all help:

LinAlg.h

//// PROTECT HEADER
#pragma once


//// IMPORT LIBRARIES
// standard modules
#include <exception>
// custom modules



//// DEFINE OBJECT
namespace LinAlg
{
    class ktaArr
    {
    public:
        // INIT
        ktaArr(int w, int h);
        ktaArr(int w, int h, double val);
        // SETTERS
        void SetValue(int row, int col, double val);
        // GETTERS
        int GetWidth();
        int GetHeight();
        double GetValue(int row, int col);
        // METHODS
        ktaArr dot(ktaArr arr2);
        void Display();
        // OPPERATORS
        ktaArr operator=(ktaArr arr2);
        ktaArr operator+(ktaArr arr2);
        ktaArr operator-(ktaArr arr2);
        ktaArr operator*(ktaArr arr2);
        ktaArr operator/(ktaArr arr2);
        // RELATIONS
        bool operator==(ktaArr arr2);
        bool operator<=(ktaArr arr2);
        bool operator>=(ktaArr arr2);
        bool operator!=(ktaArr arr2);
        // DECONSTRUCTOR
        ~ktaArr()
        {
            for(int i = 0; i < h; i++)
            {
                delete arr[i];
            }
        };

    protected:
        int w, h;
        double** arr;

    private:


    };
}

//// DEFINE EXCEPTION
namespace LinAlg
{
    class IllegalArraySize: public std::exception {
    private:
        virtual const char* what() const throw()
        {
            return "Invalid use: array sizes do not match.";
        }
    };
}

LinAlg.cpp

//// IMPORT LIBRARIES
// standard modules
#include <iostream>
// custom modules
#include "LinAlg.h"


///////////////////////////////////////////////////////////////////////////////
// INIT

LinAlg::ktaArr::ktaArr(int h, int w)
{
    LinAlg::ktaArr::w = w;
    LinAlg::ktaArr::h = h;
//  LinAlg::ktaArr::arr = new double[LinAlg::ktaArr::h][LinAlg::ktaArr::w];
    LinAlg::ktaArr::arr = new double*[LinAlg::ktaArr::h];
    for (int col = 0; col < LinAlg::ktaArr::w; col++)
    {
        LinAlg::ktaArr::arr[col] = new double[LinAlg::ktaArr::w];
    }
}

LinAlg::ktaArr::ktaArr(int h, int w, double val)
{
    LinAlg::ktaArr::w = w;
    LinAlg::ktaArr::h = h;
//  LinAlg::ktaArr::arr = new double[LinAlg::ktaArr::h][LinAlg::ktaArr::w];
    LinAlg::ktaArr::arr = new double*[LinAlg::ktaArr::h];
    for (int col = 0; col < LinAlg::ktaArr::w; col++)
    {
        LinAlg::ktaArr::arr[col] = new double[LinAlg::ktaArr::w];
    }

    //iterate over array and set values to val
    for (int row = 0; row < LinAlg::ktaArr::h; row++)
    {
        for (int col = 0; col < LinAlg::ktaArr::w; col++)
        {
            LinAlg::ktaArr::arr[row][col] = val;
        }
    }
}

// INIT
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// SETTERS

void LinAlg::ktaArr::SetValue(int row, int col, double val)
{
    if ((row+1 > LinAlg::ktaArr::h) || (col+1 > LinAlg::ktaArr::w))
    {
        throw LinAlg::IllegalArraySize();
    }
    LinAlg::ktaArr::arr[row][col] = val;
}

// SETTERS
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// GETTERS

int LinAlg::ktaArr::GetWidth()
{
    return LinAlg::ktaArr::w;
}

int LinAlg::ktaArr::GetHeight()
{
    return LinAlg::ktaArr::h;
}

double LinAlg::ktaArr::GetValue(int row, int col)
{
    return LinAlg::ktaArr::arr[row][col];
}

// GETTERS
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// METHODS

LinAlg::ktaArr LinAlg::ktaArr::dot(LinAlg::ktaArr arr2)
{
    // Check size of arrays first
    if (LinAlg::ktaArr::h != arr2.GetHeight())
    {
        throw LinAlg::IllegalArraySize();
    }

    // Create new array
    LinAlg::ktaArr arrNew(LinAlg::ktaArr::h, arr2.GetWidth());
    // Assign each value
    double value;
    for (int row = 0; row < arrNew.GetHeight(); row++)
    {
        for (int col = 0; col < arrNew.GetWidth(); col++)
        {
            value = 0;
            // Perform multiplication
            for (int el = 0; el < w; el++)
            {
                value += LinAlg::ktaArr::arr[row][el] *
                         arr2.GetValue(el, col);
            }
            arrNew.SetValue(row, col, value);
        }
    }

    return arrNew;
}

void LinAlg::ktaArr::Display()
{
    for (int row = 0; row < LinAlg::ktaArr::h; row++)
    {
        for (int col = 0; col < LinAlg::ktaArr::w; col++)
        {
            if ((row == 0) && (col == 0))
            {
                // first element
                std::cout << "[[" << LinAlg::ktaArr::arr[row][col];
            }
            else if ((row == LinAlg::ktaArr::h-1) &&
                     (col == LinAlg::ktaArr::w-1))
            {
                // last element
                std::cout << ", " << LinAlg::ktaArr::arr[row][col]
                          << "]]" << std::endl;
            }
            else if ((row != 0) && (col == 0))
            {
                // first element of row
                std::cout << " [" << LinAlg::ktaArr::arr[row][col];
            }
            else if ((row != LinAlg::ktaArr::h-1) &&
                     (col == LinAlg::ktaArr::w-1))
            {
                // last element of row
                std::cout << ", " << LinAlg::ktaArr::arr[row][col]
                          << "]" << std::endl;
            }
            else
            {
                // print out value
                std::cout << ", " << LinAlg::ktaArr::arr[row][col];
            }
        }
    }
}

// METHODS
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// OPPERATORS

LinAlg::ktaArr LinAlg::ktaArr::operator=(LinAlg::ktaArr arr2)
{
    LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                           arr2.GetWidth());
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            newArr.SetValue(row, col, arr2.GetValue(row,col));
        }
    }
    return newArr;
}

LinAlg::ktaArr LinAlg::ktaArr::operator+(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                           arr2.GetWidth());
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            newArr.SetValue(row, col,
                            LinAlg::ktaArr::arr[row][col]
                                + arr2.GetValue(row,col));
        }
    }
    return newArr;
}

LinAlg::ktaArr LinAlg::ktaArr::operator-(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                           arr2.GetWidth());
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            newArr.SetValue(row, col,
                            LinAlg::ktaArr::arr[row][col]
                                - arr2.GetValue(row,col));
        }
    }
    return newArr;
}

LinAlg::ktaArr LinAlg::ktaArr::operator*(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                           arr2.GetWidth());
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            newArr.SetValue(row, col,
                            LinAlg::ktaArr::arr[row][col]
                                * arr2.GetValue(row,col));
        }
    }
    return newArr;
}

LinAlg::ktaArr LinAlg::ktaArr::operator/(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    LinAlg::ktaArr newArr = LinAlg::ktaArr(arr2.GetHeight(),
                           arr2.GetWidth());
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            newArr.SetValue(row, col,
                            LinAlg::ktaArr::arr[row][col]
                                / arr2.GetValue(row,col));
        }
    }
    return newArr;
}

// OPPERATORS
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// RELEATIONS

bool LinAlg::ktaArr::operator==(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            if (LinAlg::ktaArr::arr[row][col] != arr2.GetValue(row, col))
            {
                return false;
            }
        }
    }
    return true;
}

bool LinAlg::ktaArr::operator<=(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            if (LinAlg::ktaArr::arr[row][col] >= arr2.GetValue(row, col))
            {
                return false;
            }
        }
    }
    return true;
}

bool LinAlg::ktaArr::operator>=(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            if (LinAlg::ktaArr::arr[row][col] <= arr2.GetValue(row, col))
            {
                return false;
            }
        }
    }
    return true;
}

bool LinAlg::ktaArr::operator!=(LinAlg::ktaArr arr2)
{
    if ((LinAlg::ktaArr::h != arr2.GetHeight()) ||
        (LinAlg::ktaArr::w != arr2.GetWidth()))
    {
        throw LinAlg::IllegalArraySize();
    }
    for(int row = 0; row < arr2.GetHeight(); row++)
    {
        for(int col = 0; col < arr2.GetWidth(); col++)
        {
            if (LinAlg::ktaArr::arr[row][col] == arr2.GetValue(row, col))
            {
                return false;
            }
        }
    }
    return true;
}

// RELATIONS
///////////////////////////////////////////////////////////////////////////////

main.cpp

//// IMPORT LIBRARIES
// standard modules
#include <iostream>
// custom modules
#include "../LinAlgLib/LinAlg.h"

int main()
{
    LinAlg::ktaArr identity (3,3,0.0);
    std::cout << "Display 3x3 zeros array:" << std::endl;
    identity.Display();
    std::cout << "test" << std::endl;
    return 0;
}

Everything is done on Mac OSX 10.9, using GCC as follows:

LinAlg library

make all 
Building file: ../LinAlg.cpp
Invoking: Cross G++ Compiler
g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"LinAlg.d" -MT"LinAlg.d" -o "LinAlg.o" "../LinAlg.cpp"
Finished building: ../LinAlg.cpp

Building target: libLinAlg.so
Invoking: Cross G++ Linker
g++ -shared -o "libLinAlg.so"  ./LinAlg.o   
Finished building target: libLinAlg.so

Test app (main.cpp):

make all 
Building file: ../main.cpp
Invoking: Cross G++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
Finished building: ../main.cpp

Building target: testKyleLinAlg
Invoking: Cross G++ Linker
g++  -o "testKyleLinAlg"  ./main.o   
Undefined symbols for architecture x86_64:
  "LinAlg::ktaArr::ktaArr(int, int, double)", referenced from:
      _main in main.o
  "LinAlg::ktaArr::Display()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [testKyleLinAlg] Error 1

Thanks again for any/all help.

Joe
  • 41,484
  • 20
  • 104
  • 125
user3225826
  • 31
  • 1
  • 2
  • 3
    Your link step `g++ -o "testKyleLinAlg" ./main.o ` does not include `LinAlg.o` – Joe Jan 23 '14 at 01:16
  • I would really recommend using Xcode or netbeans. They would do this for you automatically. – 735Tesla Jan 23 '14 at 01:21
  • I will give it a try. I (when I know what I am doing) intend to actually start writing my own makefiles that will do everything (I like having control, but I thought eclipse would be a good start). – user3225826 Jan 23 '14 at 02:05
  • Thank you Joe, that worked. I have looked and haven't received a decent answer: What the bloody hell is a .o file versus .d file versus .so versus .dynlib (latter two I think have to do with type of library but I'm still not sure of)? – user3225826 Jan 23 '14 at 02:17
  • Much like a .dll on Windows systems, a .so is a dynamically linked lib traditionally used on linux systems, and a .dylib is a dynamically linked lib used on OSX (Xcode). – Sir Digby Chicken Caesar Aug 14 '14 at 07:57
  • The ".o" files are the intermediate object files corresponding to compiled source files / modules, where the ".d" files are likely used by the make system to perform incremental linking so that it can avoid recompiling an entire .o file when the source associated with that .o file changes(if the object files are relatively large). – Sir Digby Chicken Caesar Aug 14 '14 at 08:01

0 Answers0