Compile error with virtual inheritance: const <anonymous>**

T

Thomas Zangl

Hi!

I have a class hierachie like this:

// interface, abstract only
class ISession {

}

// implements common parts of ISession
class Session: public virtual ISession {
public:
Session(Socket* conn);

}

// implements the rest of ISession
class FTPSession: public virtual Session {
public:
FTPSession(Socket* conn);
}

I get this error on compile:

g++ -c -g -Wall -O2 -I./include -o src/FTPSession.o src/FTPSession.cpp
src/FTPSession.cpp: In constructor `
FTPServer_::FTPSession::FTPSession(FTPServer_::Socket*)':
src/FTPSession.cpp:17: error: no matching function for call to `
FTPServer_::Session::Session(const <anonymous>**)'
include/Session.h:10: error: candidates are:
FTPServer_::Session::Session(const
FTPServer_::Session&)
include/Session.h:12: error:
FTPServer_::Session::Session(FTPServer_::Socket*)
make: *** [src/FTPSession.o] Error 1

Any ideas?

TIA,
 
V

Victor Bazarov

Thomas said:
I have a class hierachie like this:

// interface, abstract only
class ISession {

}
;
// implements common parts of ISession
class Session: public virtual ISession {
public:
Session(Socket* conn);

} ;

// implements the rest of ISession
class FTPSession: public virtual Session {
public:
FTPSession(Socket* conn);
}
;
I get this error on compile:

g++ -c -g -Wall -O2 -I./include -o src/FTPSession.o src/FTPSession.cpp
src/FTPSession.cpp: In constructor `
FTPServer_::FTPSession::FTPSession(FTPServer_::Socket*)':

Is 'FTPServer_' a namespace you forgot to mention?

Where is the code for the constructor?
src/FTPSession.cpp:17: error: no matching function for call to `
FTPServer_::Session::Session(const <anonymous>**)'
include/Session.h:10: error: candidates are:
FTPServer_::Session::Session(const
FTPServer_::Session&)
include/Session.h:12: error:
FTPServer_::Session::Session(FTPServer_::Socket*)
make: *** [src/FTPSession.o] Error 1

Any ideas?

Post the actual code you are trying to compile.

V
 
M

mlimber

Thomas said:
Hi!

I have a class hierachie like this:

// interface, abstract only
class ISession {

}

// implements common parts of ISession
class Session: public virtual ISession {
public:
Session(Socket* conn);

}

// implements the rest of ISession
class FTPSession: public virtual Session {
public:
FTPSession(Socket* conn);
}

I get this error on compile:

g++ -c -g -Wall -O2 -I./include -o src/FTPSession.o src/FTPSession.cpp
src/FTPSession.cpp: In constructor `
FTPServer_::FTPSession::FTPSession(FTPServer_::Socket*)':
src/FTPSession.cpp:17: error: no matching function for call to `
FTPServer_::Session::Session(const <anonymous>**)'
include/Session.h:10: error: candidates are:
FTPServer_::Session::Session(const
FTPServer_::Session&)
include/Session.h:12: error:
FTPServer_::Session::Session(FTPServer_::Socket*)
make: *** [src/FTPSession.o] Error 1

Any ideas?

TIA,
--

I'm guessing that the body or initialization list of FTPSession has the
error. Post the code for that.

Cheers! --M
 
T

Thomas Zangl

Victor Bazarov wrote:

Hi!
Is 'FTPServer_' a namespace you forgot to mention?

Yes - sorry.
Where is the code for the constructor?

Here:

#include "FTPSession.h"
#include "StringUtils.h"
#include "Parameter.h"
#include "CommandFactory.h"
#include "Socket.h"

#include <iostream>
#include <sstream>
#include <unistd.h>

using StringUtils_::int2str;

namespace FTPServer_
{

//-----------------------------------------------------------------------------
FTPSession::FTPSession(Socket *conn)
{
/*
* :
data_conn_(0),
is_logged_in_(false)
*/

// get init command, only used to send a "220 CPP Server ready"
// to the client
start_command_ = CommandFactory::getInstance().getInit();
required_fd_ = conn_->getSocket();

// setup the jail for all filesystem functions
// use current_working_dir if possible otherwise /tmp
char* buf = new char[sizeof(char) * PATH_MAX];
if ( getcwd(buf, PATH_MAX) == 0 ){
std::cout << "Cannot get current working directory (using /tmp
instead)" << std::endl;
fs_.setRootDirectory("/tmp");
} else {
std::string strbuf(buf);
std::cout << "Setting current working directory to: " << strbuf
<< std::endl;
fs_.setRootDirectory(strbuf);
}
delete buf;
}
.... // more code needed?

TIA!
 
B

Bob Hairgrove

// setup the jail for all filesystem functions
// use current_working_dir if possible otherwise /tmp
char* buf = new char[sizeof(char) * PATH_MAX];
if ( getcwd(buf, PATH_MAX) == 0 ){
std::cout << "Cannot get current working directory (using /tmp
instead)" << std::endl;
fs_.setRootDirectory("/tmp");
} else {
std::string strbuf(buf);
std::cout << "Setting current working directory to: " << strbuf
<< std::endl;
fs_.setRootDirectory(strbuf);
}
delete buf;
}
.... // more code needed?

This is not exception safe. It would be better to use vector<char>
instead of new and delete, i.e.:

// setup the jail for all filesystem functions
// use current_working_dir if possible otherwise /tmp
// char* buf = new char[sizeof(char) * PATH_MAX];
//----------------------------
std::vector<char> buf(PATH_MAX);
// sizeof(char) is ALWAYS == 1 !
//----------------------------
if ( getcwd(&(buf[0]), PATH_MAX) == 0 ){
std::cout << "Cannot get current working directory"
" (using /tmp instead)" << std::endl;
fs_.setRootDirectory("/tmp");
} else {
std::string strbuf(&(buf[0]));
std::cout << "Setting current working directory to: "
<< strbuf << std::endl;
fs_.setRootDirectory(strbuf);
}
//----------------------------
// no need for this now:
// delete buf;
//----------------------------
}

Since the C++ standard as well as all existing implementations
guarantee that std::vector<char> will be gontiguous in memory, passing
the address of the first vector element instead of an array to legacy
functions expecting a char array is guaranteed to work.
 
L

Lyon

I think the virtual inheritance means "SHARE" the parent class, thus
the parent class should not be an abstract class. It should create an
instance and all the subclasses will share it, is that true?
 
M

mlimber

Bob said:
// setup the jail for all filesystem functions
// use current_working_dir if possible otherwise /tmp
char* buf = new char[sizeof(char) * PATH_MAX]; [snip]
delete buf;
}
.... // more code needed?

This is not exception safe. It would be better to use vector<char>
instead of new and delete, i.e.:
[snip]

Moreover, the sizeof(char) in your new statement is useless.

As for Bob's point, I agree whole-heartedly. See also this FAQ:

http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1

Cheers! --M
 
V

Victor Bazarov

Thomas said:
#include "FTPSession.h"
#include "StringUtils.h"
#include "Parameter.h"
#include "CommandFactory.h"
#include "Socket.h"

#include <iostream>
#include <sstream>
#include <unistd.h>

using StringUtils_::int2str;

namespace FTPServer_
{

//-----------------------------------------------------------------------------

FTPSession::FTPSession(Socket *conn)

Here you don't have any initialisation list. That means that the base
class subobject is default-initialised. There is no default constructor
in 'Session' You need to probably initialise it here explicitly with the
'conn' argument. Add:

: Session(conn)

here.

V
 
M

mlimber

Thomas Zangl wrote:
[snip]
#include "FTPSession.h"
#include "StringUtils.h"
#include "Parameter.h"
#include "CommandFactory.h"
#include "Socket.h"

#include <iostream>
#include <sstream>
#include <unistd.h>

using StringUtils_::int2str;

namespace FTPServer_
{

//-----------------------------------------------------------------------------
FTPSession::FTPSession(Socket *conn)
{
/*
* :
data_conn_(0),
is_logged_in_(false)
*/

// get init command, only used to send a "220 CPP Server ready"
// to the client
start_command_ = CommandFactory::getInstance().getInit();
required_fd_ = conn_->getSocket();

// setup the jail for all filesystem functions
// use current_working_dir if possible otherwise /tmp
char* buf = new char[sizeof(char) * PATH_MAX];
if ( getcwd(buf, PATH_MAX) == 0 ){
std::cout << "Cannot get current working directory (using /tmp
instead)" << std::endl;
fs_.setRootDirectory("/tmp");
} else {
std::string strbuf(buf);
std::cout << "Setting current working directory to: " << strbuf
<< std::endl;
fs_.setRootDirectory(strbuf);
}
delete buf;
}
.... // more code needed?

You're missing the initialization (constructor call) for the base class
Session. Try:

FTPSession::FTPSession(Socket *conn)
: Session( conn )
{
// ...
}


Cheers! --M
 

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,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top