Problem with Inheritance

Discussion in 'C++' started by Gama Franco, Aug 28, 2004.

  1. Gama Franco

    Gama Franco Guest

    Hi,

    I've been developing this API, but now I get stuck in a compiling error
    and I'm out of ideas. Some comments are welcome.

    The hierarchy is bases in three classes, and I will explain it bellow in
    detail.

    The three classes are:
    1 - IFolderManager -> abstract base class
    2 - FolderManagerCommon : public IFolderManager
    3 - FolderManager : public FolderManagerCommon

    The properties of this relation are:

    1 - IFolderManager has only abstract methods and no attributes.

    2 - IFolderManagerCommon implements a small set of methods from the base
    class.
    3 - IFolderManagerCommon declares and implements some protected methods,
    and as some private attributes.
    4 - IFolderManagerCommon has no constructors, since it is also an
    abstract class (doesn't implement all the methods from the base class).

    5 - FolderManager implements all the methods from the base class that
    are not implemented by FolderManagerCommon.

    6 - All the three classes have virtual destructors.
    7 - All methods are virtual.
    8 - Only FolderManager has constructors.

    From this description we see that the union of FolderManagerCommon and
    FolderManager implement all the methods declared by the interface (base
    class).

    The problem is that when I compile the code I get the following error:
    .../src/common/FolderManagerCommon.h:7: error: candidates are:
    FolderManagerCommon::FolderManagerCommon(const FolderManagerCommon&)

    This error points to the constructor of FolderManager, in
    FolderManager.cxx. And I have no ideia of what is going on.

    I've tried to explain to resume the error, so that there was no need to
    look at the code. But I will place the code here also, in case I
    couldn't explain myself:
    --------------------------------------------------------------
    IFolderManager.h
    --------------------------------------------------------------
    #ifndef IFOLDERMANAGER_H
    #define IFOLDERMANAGER_H
    #include "ITableManager.h"
    #include <vector>
    #include <string>
    using namespace std;

    /** @interface
    * @stereotype base_class */
    class IFolderManager {

    public:
    virtual IFolderManager* createFolder(const string& folderName,
    const string& folderAttributes,
    const string& folderDescription) const
    throw (TIDB_Exception) =0;

    virtual ITableManager* createTable(const string& tableName,
    ICondDBTable& table,
    const string& tableAttributes,
    const string& tableDescription) const
    throw(TIDB_Exception)=0;

    virtual void deleteFolder(const string& folderName) const
    throw (TIDB_Exception) = 0;

    virtual void deleteTable(const string& tableName) const
    throw (TIDB_Exception) = 0;

    virtual IFolderManager* getFolderManager(const string& folderName)
    const
    throw(TIDB_Exception)= 0;

    virtual vector < IFolderManager >* getFolderManagers() const
    throw(TIDB_Exception) = 0;

    virtual ITableManager* getTableManager(const string& tableName) const
    throw(TIDB_Exception) = 0;

    virtual vector < ITableManager >* getTableManagers() const
    throw(TIDB_Exception)= 0;

    virtual const string& getDescription() const =0;

    virtual const string& getPath() const =0;

    virtual const string& getVersion() const=0;

    virtual ~IFolderManager() {} //dummy destructor
    };
    #endif //IFOLDERMANAGER_H


    --------------------------------------------------------------
    IFolderManagerCommon.h
    --------------------------------------------------------------
    #ifndef FOLDERMANAGERCOMMON_H
    #define FOLDERMANAGERCOMMON_H

    #include "IFolderManager.h"
    #include "../common/IDatabase.h"

    class FolderManagerCommon : public IFolderManager {


    public:
    virtual const string& getDescription() const;

    virtual const string& getPath() const;

    virtual const string& getVersion() const;

    virtual ~FolderManagerCommon();

    protected:
    virtual const IDatabase& getDatabase() const;

    private:
    string path;
    string version;
    string description;
    IDatabase& database;
    };

    #endif // FOLDERCOMMON_H


    --------------------------------------------------------------
    FolderManager.h
    --------------------------------------------------------------
    #ifndef FOLDERMANAGER_H
    #define FOLDERMANAGER_H
    #include "../common/FolderManagerCommon.h"

    /**
    * @stereotype Oracle
    */
    class FolderManager : public FolderManagerCommon {

    public:
    FolderManager(const string& path, const IDatabase& database);

    virtual IFolderManager* createFolder(const string& folderName,
    const string& folderAttributes,
    const string& folderDescription) const
    throw (TIDB_Exception);

    virtual ITableManager* createTable(const string& tableName,
    ICondDBTable& table,
    const string& tableAttributes,
    const string& tableDescription) const
    throw (TIDB_Exception);

    virtual void deleteFolder(const string& folderName) const
    throw (TIDB_Exception);

    virtual void deleteTable(const string& tableName) const
    throw (TIDB_Exception);

    virtual IFolderManager* getFolderManager(const string& folderName)
    const
    throw (TIDB_Exception);

    virtual vector < IFolderManager >* getFolderManagers() const
    throw (TIDB_Exception);

    virtual ITableManager* getTableManager(const string& tableName) const
    throw (TIDB_Exception);

    virtual vector < ITableManager >* getTableManagers() const
    throw (TIDB_Exception);

    virtual ~FolderManager();

    private:

    /** @link dependency */
    /*# P_Folder lnkFolder; */

    /** @link dependency */
    /*# P_Table lnkTable; */
    };
    #endif //FOLDERMANAGER_H
     
    Gama Franco, Aug 28, 2004
    #1
    1. Advertising

  2. Gama Franco wrote:
    ....
    >
    > The problem is that when I compile the code I get the following error:
    > ../src/common/FolderManagerCommon.h:7: error: candidates are:
    > FolderManagerCommon::FolderManagerCommon(const FolderManagerCommon&)
    >
    > This error points to the constructor of FolderManager, in
    > FolderManager.cxx. And I have no ideia of what is going on.


    It seems you have missed putting FolderManager.cxx in your code snippet.
    I have not been able to reproduce the error you describe with the code
    you have posted.

    Please post a complete, compileable snippet of code that demonstrates
    the problem you describe.

    Anyhow, you do mention "error points to the constructor of
    FolderManager". FolderManager has no declared constructor so it's using
    the default constructor generated by the compiler. It seems you are
    defining a new one in the .cxx file which is probably an error.

    >
    > I've tried to explain to resume the error, so that there was no need to
    > look at the code. But I will place the code here also, in case I
    > couldn't explain myself:


    .... the code below, which does not have any errors under gcc 3.4, was
    taken from your original post.

    #include <vector>
    #include <string>
    using namespace std;

    struct TIDB_Exception {};
    struct ITableManager {};
    struct ICondDBTable {};
    struct IDatabase {};

    /** @interface
    * @stereotype base_class */
    class IFolderManager {

    public:
    virtual IFolderManager* createFolder(const string& folderName,
    const string& folderAttributes,
    const string& folderDescription) const
    throw (TIDB_Exception) =0;

    virtual ITableManager* createTable(const string& tableName,
    ICondDBTable& table,
    const string& tableAttributes,
    const string& tableDescription) const
    throw(TIDB_Exception)=0;

    virtual void deleteFolder(const string& folderName) const
    throw (TIDB_Exception) = 0;

    virtual void deleteTable(const string& tableName) const
    throw (TIDB_Exception) = 0;

    virtual IFolderManager* getFolderManager(const string& folderName)
    const
    throw(TIDB_Exception)= 0;

    virtual vector < IFolderManager >* getFolderManagers() const
    throw(TIDB_Exception) = 0;

    virtual ITableManager* getTableManager(const string& tableName) const
    throw(TIDB_Exception) = 0;

    virtual vector < ITableManager >* getTableManagers() const
    throw(TIDB_Exception)= 0;

    virtual const string& getDescription() const =0;

    virtual const string& getPath() const =0;

    virtual const string& getVersion() const=0;

    virtual ~IFolderManager() {} //dummy destructor
    };


    class FolderManagerCommon : public IFolderManager {


    public:
    virtual const string& getDescription() const;

    virtual const string& getPath() const;

    virtual const string& getVersion() const;

    virtual ~FolderManagerCommon();

    protected:
    virtual const IDatabase& getDatabase() const;

    private:
    string path;
    string version;
    string description;
    IDatabase& database;
    };

    /**
    * @stereotype Oracle
    */
    class FolderManager : public FolderManagerCommon {

    public:
    FolderManager(const string& path, const IDatabase& database);

    virtual IFolderManager* createFolder(const string& folderName,
    const string& folderAttributes,
    const string& folderDescription) const
    throw (TIDB_Exception);

    virtual ITableManager* createTable(const string& tableName,
    ICondDBTable& table,
    const string& tableAttributes,
    const string& tableDescription) const
    throw (TIDB_Exception);

    virtual void deleteFolder(const string& folderName) const
    throw (TIDB_Exception);

    virtual void deleteTable(const string& tableName) const
    throw (TIDB_Exception);

    virtual IFolderManager* getFolderManager(const string& folderName)
    const
    throw (TIDB_Exception);

    virtual vector < IFolderManager >* getFolderManagers() const
    throw (TIDB_Exception);

    virtual ITableManager* getTableManager(const string& tableName) const
    throw (TIDB_Exception);

    virtual vector < ITableManager >* getTableManagers() const
    throw (TIDB_Exception);

    virtual ~FolderManager();

    private:

    /** @link dependency */
    /*# P_Folder lnkFolder; */

    /** @link dependency */
    /*# P_Table lnkTable; */
    };
     
    Gianni Mariani, Aug 28, 2004
    #2
    1. Advertising

  3. Gama Franco

    David Hilsee Guest

    "Gama Franco" <> wrote in message
    news:41309519$0$1780$...
    > Hi,
    >
    > I've been developing this API, but now I get stuck in a compiling error
    > and I'm out of ideas. Some comments are welcome.
    >
    > The hierarchy is bases in three classes, and I will explain it bellow in
    > detail.
    >
    > The three classes are:
    > 1 - IFolderManager -> abstract base class
    > 2 - FolderManagerCommon : public IFolderManager
    > 3 - FolderManager : public FolderManagerCommon
    >
    > The properties of this relation are:
    >
    > 1 - IFolderManager has only abstract methods and no attributes.
    >
    > 2 - IFolderManagerCommon implements a small set of methods from the base
    > class.
    > 3 - IFolderManagerCommon declares and implements some protected methods,
    > and as some private attributes.
    > 4 - IFolderManagerCommon has no constructors, since it is also an
    > abstract class (doesn't implement all the methods from the base class).


    I just want to point out that abstract classes may need to have
    constructors. In fact, in your case, I would expect IFolderManagerCommon to
    have constructors, because it has private data that it must initialize. If
    you like, they may be protected, but they should still exist.

    > 5 - FolderManager implements all the methods from the base class that
    > are not implemented by FolderManagerCommon.
    >
    > 6 - All the three classes have virtual destructors.
    > 7 - All methods are virtual.
    > 8 - Only FolderManager has constructors.
    >
    > From this description we see that the union of FolderManagerCommon and
    > FolderManager implement all the methods declared by the interface (base
    > class).
    >
    > The problem is that when I compile the code I get the following error:
    > ../src/common/FolderManagerCommon.h:7: error: candidates are:
    > FolderManagerCommon::FolderManagerCommon(const FolderManagerCommon&)
    >
    > This error points to the constructor of FolderManager, in
    > FolderManager.cxx. And I have no ideia of what is going on.


    You didn't provide the source to FolderManager.cxx, and it looks like you
    didn't provide all of the compiler's messages. It's difficult to figure out
    what the compiler's complaining about if you can't see the relevant
    information. Consider posting that information if you aren't getting the
    help you need.

    <snip>
    > class FolderManagerCommon : public IFolderManager {
    >
    >
    > public:
    > virtual const string& getDescription() const;
    >
    > virtual const string& getPath() const;
    >
    > virtual const string& getVersion() const;
    >
    > virtual ~FolderManagerCommon();
    >
    > protected:
    > virtual const IDatabase& getDatabase() const;
    >
    > private:
    > string path;
    > string version;
    > string description;
    > IDatabase& database;
    > };

    <snip>

    How do you expect "database" to be initialized? This class needs a
    constructor.

    --
    David Hilsee
     
    David Hilsee, Aug 28, 2004
    #3
  4. Gama Franco

    Gama Franco Guest

    Hi,

    I'm sorry to post with a different e-mail, but the Newsgroup's Server
    of my ISP is not working and I had to use a (very) old google account.

    There are some points that I don't understand. Why does an abstract
    class need a constructor, and how can an abstract class have a
    constructor?
    For what I remember, it is not possible to create objects of an
    abstract class... or is it?

    Also, what is the definition of 'default constructor'? Is the one
    without arguments?

    The set of classes "Database" use the same technique (one Interface,
    one Common and a final class)... the strange is that I don't get a
    compiler error for those three classes, but that must happen because
    of some detail that I don't know of.
    I'm also not sure if the Database classe finish compilation, because
    IDatabase 'includes' IFolderManager.


    Now I post the compiler errors:

    #########The one related to the constructor
    .../src/Oracle/FolderManager.cxx: In constructor
    `FolderManager::FolderManager(const std::string&, const IDatabase&)':
    .../src/Oracle/FolderManager.cxx:4: error: no matching function for
    call to `FolderManagerCommon::FolderManagerCommon()'

    #########Related to the inheritence IFolderManager <--
    FolderManagerCommon
    .../src/common/FolderManagerCommon.h:7: error: candidates are:
    FolderManagerCommon::FolderManagerCommon(const FolderManagerCommon&)



    Bellow I will post FolderManagerCommon.cxx and FolderManager.cxx

    ================================================================
    FolderManagerCommon.cxx
    ================================================================
    #include "FolderManagerCommon.h"

    const string& FolderManagerCommon::getDescription() const{
    return this->description;
    }

    const string& FolderManagerCommon::getPath() const{
    return this->path;
    }

    const string& FolderManagerCommon::getVersion() const {
    return this->version;
    }

    FolderManagerCommon::~FolderManagerCommon()
    {
    }

    //protected methods
    const IDatabase& FolderManagerCommon::getDatabase() const{
    return this->database;
    }


    ================================================================
    FolderManager.cxx
    ================================================================
    #include "FolderManager.h"

    FolderManager::FolderManager(const string& path, const IDatabase&
    database)
    {
    //TODO
    }

    ITableManager* FolderManager::getTableManager(const string& tableName)
    const
    throw (TIDB_Exception)
    {
    //TODO
    return NULL;
    }

    vector < ITableManager >* FolderManager::getTableManagers() const
    throw (TIDB_Exception)
    {
    //TODO
    return new vector < ITableManager >;
    }

    ITableManager* FolderManager::createTable(const string& tableName,
    ICondDBTable& table,
    const string& tableAttributes,
    const string& tableDescription) const
    throw (TIDB_Exception)
    {
    //TODO
    return NULL;
    }

    void FolderManager::deleteTable(const string& tableName) const
    throw (TIDB_Exception)
    {
    //TODO
    }
    void FolderManager::deleteFolder(const string& folderName) const
    throw (TIDB_Exception)
    {
    //TODO
    }

    IFolderManager* FolderManager::createFolder(
    const string& folderName,
    const string& folderAttributes,
    const string& folderDescription) const
    throw (TIDB_Exception)
    {
    //TODO
    return new FolderManager( "/" + folderName, this->getDatabase());
    }

    IFolderManager* FolderManager::getFolderManager(const string&
    folderName) const
    throw (TIDB_Exception) {
    //TODO
    return new FolderManager( "/" + folderName, this->getDatabase());
    }

    vector < IFolderManager >* FolderManager::getFolderManagers() const
    throw (TIDB_Exception)
    {
    //TODO
    return new vector<IFolderManager >;
    }

    FolderManager::~FolderManager()
    {

    }



    Thanks in advance,
    Gama Franco
     
    Gama Franco, Aug 29, 2004
    #4
  5. Gama Franco wrote:
    ....

    > There are some points that I don't understand. Why does an abstract
    > class need a constructor, and how can an abstract class have a
    > constructor?


    You can certainly have a constructor for an abstract class. The term
    "abstract" class means that the class cannot be instantiated by itself.

    > For what I remember, it is not possible to create objects of an
    > abstract class... or is it?


    It is if you inherit from it - but not by itself.

    >
    > Also, what is the definition of 'default constructor'? Is the one
    > without arguments?


    Yes. However, don't be confused by the default constructor provided by
    the compiler and the default constructor that may be defined.

    ....
    >
    >
    > Now I post the compiler errors:
    >
    > #########The one related to the constructor
    > ../src/Oracle/FolderManager.cxx: In constructor
    > `FolderManager::FolderManager(const std::string&, const IDatabase&)':
    > ../src/Oracle/FolderManager.cxx:4: error: no matching function for
    > call to `FolderManagerCommon::FolderManagerCommon()'
    >
    > #########Related to the inheritence IFolderManager <--
    > FolderManagerCommon
    > ../src/common/FolderManagerCommon.h:7: error: candidates are:
    > FolderManagerCommon::FolderManagerCommon(const FolderManagerCommon&)
    >
    >
    >
    > Bellow I will post FolderManagerCommon.cxx and FolderManager.cxx


    ....

    This is your problem. You are defining a constructor which needs (and
    will) instantiate the constructor for it's inherited classes (in this
    case FolderManagerCommon ). In this case it seems like gcc does not
    create a default constructor for FolderManagerCommon most likely because
    you need to initialize FolderManagerCommon::database. Since
    FolderManagerCommon::database is a reference it can only be bound by the
    constructor and the compiler has no way of knowing how to do it and
    hence it seems like gcc in this case simply does not provide a default
    constructor. I'm not sure if this is what the standard requires but I
    for one like this behaviour (because it's likely a bug to do anything
    else anyway!).

    >
    > FolderManager::FolderManager(const string& path, const IDatabase&
    > database)
    > {
    > //TODO
    > }



    You need to do somthing like this:


    class FolderManagerCommon : public IFolderManager {
    public:

    FolderManagerCommon( const IDatabase& database )
    : database( database )
    {
    }
    ....
    const IDatabase& database;
    };

    FolderManager::FolderManager(
    const string& path, const IDatabase& database
    )
    : FolderManagerCommon( database )
    {
    //TODO
    }


    And all will be well.
     
    Gianni Mariani, Aug 29, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,144
    Martijn van Steenbergen
    Dec 21, 2003
  2. cppsks
    Replies:
    0
    Views:
    827
    cppsks
    Oct 27, 2004
  3. karthikbalaguru
    Replies:
    9
    Views:
    1,041
  4. Daniel Pitts
    Replies:
    27
    Views:
    1,904
    Mike Schilling
    Feb 27, 2008
  5. johnsonlau
    Replies:
    1
    Views:
    777
    Kai-Uwe Bux
    Jul 21, 2008
Loading...

Share This Page