Problem with Inheritance

G

Gama Franco

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
 
G

Gianni Mariani

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; */
};
 
D

David Hilsee

Gama Franco said:
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.

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.
 
G

Gama Franco

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
 
G

Gianni Mariani

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top