2

I am trying to create a shared library to use for some of my projects. The idea is to contain all classes that I use for a generic role, in this case file I/O, with an API and create instances of derived classes tailored to specific tasks. The problem is that I can't create the different instances from the different derived classes. The compiler throws errors of "multiple definition of BaseFile::create(FileObjectType)" and "multiple definition of BaseFile::destroy(BaseFile*)"

I work with linux, and Code::Blocks. I have made a header file where the API (the base class where all others inherit from) and two functions, one to create and return an instance, and one to destroy it. At a second header file, I keep the class declarations and the implementation of the member functions create and destroy, and multiple files where I implement each class.

//This is the API header file
#ifndef FILELIB_HPP_INCLUDED
#define FILELIB_HPP_INCLUDED
#include <string>
#include <fstream>
using namespace std;
//The different classes available, that inherit the base class
enum FileObjectType {
    FOT_OUTFILE, FOT_OUTFILEB, FOT_INFILE, FOT_INFILEB
};
//The base class
class BaseFile {
protected:
    string sFileName;
    int iSize;
    fstream FileStream;
public:
    virtual bool bOpenFile(string FileName);
    virtual string sReturnBlock(int IndexNumber, int BlockSize);
    virtual bool bAppendBlock(string BlockToWrite);
    virtual bool bCreateFile(string FileName);
        virtual void vCloseFile();
        //The two functions that return 
        static BaseFile* create(FileObjectType);
        static void destroy(BaseFile* prt);
    BaseFile() {};
    virtual ~BaseFile();
};
//The two functions to be exported
extern "C" BaseFile* create(FileObjectType eType);
extern "C" void destroy(BaseFile* ptr);

#endif // FILELIB_HPP_INCLUDED

The main header file where I keep the declarations:

//The header file where I keep the declarations
#ifndef MAINHEADER_HPP_INCLUDED
#define MAINHEADER_HPP_INCLUDED
#include "FileLib.hpp"
#include <iostream>
//Each specialised class declarations
class OutFile : public BaseFile {
private:
public:
    OutFile();
    ~OutFile();
};
class OutFileb : public BaseFile {
private:
public:
    OutFileb();
    ~OutFileb();
};
class InFileb : public BaseFile {
private:
public:
    InFileb();
    ~InFileb();
};
class InFile : public BaseFile {
private:
public:
    InFile();
    ~InFile();
};
//The two functions-to-be-exported implementation
BaseFile* BaseFile::create(FileObjectType eType)
{
    if (eType == FOT_OUTFILE) return new OutFile;
    if (eType == FOT_OUTFILEB) return new OutFileb;
    if (eType == FOT_INFILE) return new InFile;
    if (eType == FOT_INFILEB) return new InFileb;
    return NULL;
}
void BaseFile::destroy(BaseFile* ptr)
{
    delete ptr;
    return;
}
#endif // MAINHEADER_HPP_INCLUDED

The error of multiple definitions says that the functions create and destroy were first defined here. I've tried to declare those functions outside the BaseFile class, as standalone functions, but the same error remains.

The implementation files contain the #include for the main header file, the empty implementations of the derived classes' constructors and destructors, and nothing else. I tried to implement the factory method. Thank you for your time.

Edit: The compiler's exact errors: (Apologies but the text dump site doesn't work, so I'll dump it here too) https://pastebin.com/ZGXNBQhW

-------------- Build: Debug in FileLib (compiler: GNU GCC Compiler)---------------

g++ -shared -L/usr/lib/i386-linux-gnu obj/Debug/InFile.o obj/Debug/InFileb.o obj/Debug/main.o obj/Debug/OutFileb.o -o bin/Debug/libFileLib.so
obj/Debug/InFileb.o: In function `OutFile::~OutFile()':
/home/myuser/Projects/FileLib/MainHeader.hpp:42: multiple definition of `BaseFile::create(FileObjectType)'
obj/Debug/InFile.o:/home/myuser/Projects/FileLib/MainHeader.hpp:42: first defined here
obj/Debug/InFileb.o: In function `BaseFile::destroy(BaseFile*)':
/home/myuser/Projects/FileLib/MainHeader.hpp:50: multiple definition of `BaseFile::destroy(BaseFile*)'
obj/Debug/InFile.o:/home/myuser/Projects/FileLib/MainHeader.hpp:50: first defined here
obj/Debug/main.o: In function `OutFile::~OutFile()':
/home/myuser/Projects/FileLib/MainHeader.hpp:42: multiple definition of `BaseFile::create(FileObjectType)'
obj/Debug/InFile.o:/home/myuser/Projects/FileLib/MainHeader.hpp:42: first defined here
obj/Debug/main.o: In function `BaseFile::destroy(BaseFile*)':
/home/myuser/Projects/FileLib/MainHeader.hpp:50: multiple definition of `BaseFile::destroy(BaseFile*)'
obj/Debug/InFile.o:/home/myuser/Projects/FileLib/MainHeader.hpp:50: first defined here
obj/Debug/OutFileb.o: In function `OutFile::~OutFile()':
/home/myuser/Projects/FileLib/MainHeader.hpp:42: multiple definition of `BaseFile::create(FileObjectType)'
obj/Debug/InFile.o:/home/myuser/Projects/FileLib/MainHeader.hpp:42: first defined here
obj/Debug/OutFileb.o: In function `BaseFile::destroy(BaseFile*)':
/home/myuser/Projects/FileLib/MainHeader.hpp:50: multiple definition of `BaseFile::destroy(BaseFile*)'
obj/Debug/InFile.o:/home/myuser/Projects/FileLib/MainHeader.hpp:50: first defined here
collect2: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
12 error(s), 0 warning(s) (0 minute(s), 0 second(s))
  • 1
    Where are the functions defined second? What other definitions does the compiler point to? Show the exact and complete text of the error messages. – Igor Tandetnik May 02 '19 at 04:08
  • The functions create and destroy are not defined anywhere else at all the files. My guess is that it may be some inheritance auto-define thing, that carries on to all derived classes and the compiler counts that as multiple defines. – George T. I. May 02 '19 at 10:59
  • Your link does not seem to be working, could you please update it? Little side note: Don't use `using namespace std;` in header files. - **Still not working after your edit.** – andreee May 02 '19 at 11:20
  • Some more comments on the code (since it's tagged C++11): You should use smart pointers instead of raw pointers whenever possible (your code is a typical use case). Have a look at `unique_ptr`. Don't define default constructors/destructors unless you have to. Consider defining `default` ctors if required. Use `nullptr` instead of `NULL`. – andreee May 02 '19 at 11:24
  • Declare - don't define - functions in headers. – Igor Tandetnik May 02 '19 at 12:49
  • My thanks to everyone for all feedback and advice. The problem was solved when I moved the functions' implementation to a source file, and made them standalone instead of static member functions in the base class. Let's hope this actually works as intended, but for now it compiles! – George T. I. May 02 '19 at 13:23

0 Answers0