Pure Virtual Functions

R

Riaan

Hi Everybody,

I created an abstract class containing all my pure virtual functions. I
derived a new class from this and implemented all the functions needed.
Every time I compile, I get the error :

..\file.cpp(189) : error C2259: 'FileInterface' : cannot instantiate abstract
class due to following members:
.\../../boffice/plugins.h(39) : see declaration of 'FileInterface'
..\file.cpp(189) : warning C4259: 'class QFile *__thiscall
FileInterface::OpenFile(const class QString,enum QIODevice::OpenModeFlag)' :
pure virtual function was not defined
.\../../boffice/plugins.h(45) : see declaration of 'OpenFile'

I made sure that I implemented the functions correctly, I checked for
spelling mistakes and everything. Could somebody please give me an idea as
where to check for the problem ? I read everything I could about pure
virtual functions, and I can not see where I went wrong !

Regards
Riaan Bekker
 
?

=?ISO-8859-15?Q?Stefan_N=E4we?=

Riaan said:
Hi Everybody,

I created an abstract class containing all my pure virtual functions. I
derived a new class from this and implemented all the functions needed.
Every time I compile, I get the error :

.\file.cpp(189) : error C2259: 'FileInterface' : cannot instantiate abstract
class due to following members:
.\../../boffice/plugins.h(39) : see declaration of 'FileInterface'
.\file.cpp(189) : warning C4259: 'class QFile *__thiscall
FileInterface::OpenFile(const class QString,enum QIODevice::OpenModeFlag)' :
pure virtual function was not defined
.\../../boffice/plugins.h(45) : see declaration of 'OpenFile'

I made sure that I implemented the functions correctly, I checked for
spelling mistakes and everything. Could somebody please give me an idea as
where to check for the problem ? I read everything I could about pure
virtual functions, and I can not see where I went wrong !

Please do not show any code that could eventually help us help you!

/S
 
A

Alf P. Steinbach

* Riaan:
[multi-posting acllcc++ and clc++]

Please don't multi-post.

Please whip yourself to a bloody pulp for this transgression, and bang
your head repeatedly against a brick wall, and so on until your
innermost self whispers, nay, shouts, for all the world to hear, "I'll
never multi-post again, I _swear_!"; then see reply in acllcc++.
 
R

Riaan

Abstract Class :

//****************
//File Plugin
class FileInterface
{
public:

virtual ~FileInterface() {};

//file open and close methods
virtual QFile* OpenFile(const QString fileName, QIODevice::OpenModeFlag
fileMode) = 0;
virtual bool WriteText(QFile *file, const QString data) = 0;
virtual void Close(QFile *file) = 0;
virtual QString TranslateIOError(const int errorCode, const QString
fileName) = 0;

};

Q_DECLARE_INTERFACE(FileInterface,"annex.File/1.0")
//End File Plugin

New Class derived from abstract

#ifndef FILE_H
#define FILE_H

#include <QPluginLoader>

//GUI interface
#include <QMessageBox>

//File handling
#include <QFile>
#include <QFileInfo>

//Include the interface file
#include "../../boffice/plugins.h"

//forward declare
//class QFile;


class File : public QFile, public FileInterface
{

Q_INTERFACES(FileInterface)

public:
//constructer, copy constructer, destructor
File(QWidget *parent);
~File();

//file open and close methods
QFile* OpenFile(const QString fileName, QIODevice::OpenModeFlag
fileMode);
bool WriteText(QFile *file, const QString data) const;
void Close(QFile *file);
QString TranslateIOError(const int errorCode, const QString fileName)
const;

private:

QMessageBox *m_mb;
QWidget *m_parent;

};


#endif



#include "file.h"

//File handling
#include <QFileInfo>

//default constructor and des
File::File( QWidget *parent )
{

m_parent = parent;

//setup the message box
m_mb = new QMessageBox(m_parent);
m_mb->setWindowTitle("Annex");
m_mb->setIcon(QMessageBox::Critical);

};

File::~File()
{
delete m_mb;
m_mb = 0;
};

QFile* File::OpenFile(const QString fileName, QIODevice::OpenModeFlag
fileMode)
{
QFile *fileToOpen = new QFile(fileName);
QString errorMsg = "";
int fileStatus = 0;

if (fileToOpen->open(fileMode) == TRUE)
{
//file was open, can return the pointer
}
else
{
//file open failed
fileStatus = fileToOpen->error();
errorMsg = TranslateIOError(fileStatus,fileName);

if (errorMsg != "")
{
//display the error message if the string is not empty
m_mb->setText(errorMsg);
m_mb->exec();
}
else
{
//error could not be translated, print own error
m_mb->setText("File open for [" + fileName + "] failed !");
m_mb->exec();
}
}

return(fileToOpen);
};

bool File::WriteText(QFile *file, const QString data) const
{
QFileInfo *fileInfo = new QFileInfo(*file);
const QString fileName = fileInfo->fileName();

long bufferSize = 0;
long fileWriteBuffer = 0;
bool wrote = FALSE;

QString errorMsg = "";

//write data to file
bufferSize = data.length();
fileWriteBuffer = file->write(data.toAscii(),bufferSize);

if (fileWriteBuffer == -1)
{
//write error occured
errorMsg = TranslateIOError(file->error(),fileName);
m_mb->setText(errorMsg);
m_mb->exec();
}
else
{
if (fileWriteBuffer == 0 && bufferSize != 0)
{
//no data was written to disk
errorMsg ="[0] of [" + QString::number(bufferSize) + "] Bytes data wrote
to disk !";
m_mb->setText(errorMsg);
m_mb->exec();
}
else
{
file->flush();
wrote = TRUE;
}
}

delete fileInfo;
fileInfo = 0;

return(wrote);
};

void File::Close(QFile *file)
{
if (file->isOpen())
{
file->flush();
file->close();
}
};

QString File::TranslateIOError(const int errorCode, const QString fileName)
const
{
QString errorMsg = "";

switch (errorCode)
{

case QFile::NoError:
errorMsg = "";
break;

case QFile::ReadError:
errorMsg = "File [" + fileName + "] open failed with [Read Error] !";
break;

case QFile::WriteError:
errorMsg = "File [" + fileName + "] open failed with [Write Error] !";
break;

case QFile::FatalError:
errorMsg = "File [" + fileName + "] open failed with [Fatal Error] !";
break;

case QFile::ResourceError:
errorMsg = "File [" + fileName + "] open failed with [Resource Error] !";
break;

case QFile::OpenError:
errorMsg = "File [" + fileName + "] open failed with [Open Error] !";
break;

case QFile::AbortError:
errorMsg = "File [" + fileName + "] open failed with [The operation was
aborted] !";
break;

case QFile::TimeOutError:
errorMsg = "File [" + fileName + "] open failed with [Time Out Error] !";
break;

case QFile::UnspecifiedError:
errorMsg = "File [" + fileName + "] open failed with [Unspecified Error]
!";
break;

case QFile::RemoveError:
errorMsg = "File [" + fileName + "] could not be removed !";
break;

case QFile::RenameError:
errorMsg = "File [" + fileName + "] could not be renamed !";
break;

case QFile::positionError:
errorMsg = "Position in file [" + fileName + "] could not be changed !";
break;

case QFile::ResizeError:
errorMsg = "File [" + fileName + "] could not be resized !";
break;

case QFile::permissionsError:
errorMsg = "File [" + fileName + "] could not be accessed due to
permissions !";
break;

case QFile::CopyError:
errorMsg = "File [" + fileName + "] could not be copied !";
break;

default:
errorMsg = "File [" + fileName + "] could not be opened [Default] !";
break;
}

return(errorMsg);
};


Q_EXPORT_PLUGIN2(FileInterface,File);
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

And ... which line causes the error?
Regards, Stephan
 
D

Daniel T.

"Riaan said:
Hi Everybody,

I created an abstract class containing all my pure virtual functions. I
derived a new class from this and implemented all the functions needed.

You are incorrect in your above assertion (from your code):

class FileInterface
{
public:

virtual ~FileInterface() {};

//file open and close methods
virtual QFile* OpenFile( const QString fileName,
QIODevice::OpenModeFlag fileMode ) = 0;
virtual bool WriteText( QFile *file, const QString data ) = 0;
virtual void Close( QFile *file ) = 0;
virtual QString TranslateIOError( const int errorCode,
const QString fileName ) = 0;

};

class File : public QFile, public FileInterface
{

Q_INTERFACES( FileInterface )

public:
//constructer, copy constructer, destructor
File( QWidget *parent );
~File();

//file open and close methods
QFile* OpenFile( const QString fileName,
QIODevice::OpenModeFlag fileMode );
bool WriteText( QFile *file, const QString data ) const;
void Close( QFile *file );
QString TranslateIOError( const int errorCode,
const QString fileName ) const;
private:
QMessageBox *m_mb;
QWidget *m_parent;

};

Notice that you didn't implement the 'WriteText' and 'TranslateIOError'
member-functions, instead you created new functions with the same names
but taking different types...
 
H

Howard

Daniel T. said:
Notice that you didn't implement the 'WriteText' and 'TranslateIOError'
member-functions, instead you created new functions with the same names
but taking different types...

I don't see what you mean about "taking different types". But I DO see a
difference. Here's the declarations of those again:

from FileInterface:
virtual bool WriteText( QFile *file, const QString data ) = 0;
virtual QString TranslateIOError( const int errorCode,
const QString fileName ) = 0;

from File:
bool WriteText( QFile *file, const QString data ) const;
QString TranslateIOError( const int errorCode,
const QString fileName ) const;

The difference is that the functions are declared 'const' in File, but not
in FileInterface.

The error message, though, seems to indicate that OpenFile was not defined.
But the OP didn't indicate which line the error message referred to (we
can't tell what line 189 is from here), so it's difficult to know for sure
what the error is pointing to. I don't see a problem with OpenFile,
offhand.

-Howard
 
I

Ian Collins

Howard said:
I don't see what you mean about "taking different types". But I DO see a
difference. Here's the declarations of those again:

from FileInterface:




from File:




The difference is that the functions are declared 'const' in File, but not
in FileInterface.
So they are different and you haven't implemented all of the pure
virtuals form you base. Do this first and then see what errors you get.
 
D

Daniel T.

"Howard said:
I don't see what you mean about "taking different types".

class A {
public:
virtual void foo() const = 0;
};

class B : public A {
public:
virtual void foo();
};

In 'A::foo', 'this' is a const pointer, whereas in 'B::foo', 'this' is
NOT a const pointer. As such, they are different types. Yes, 'T*' is
freely convertible to 'const T*' but not the other way around.
 
P

Pete Becker

Daniel said:
In 'A::foo', 'this' is a const pointer, whereas in 'B::foo', 'this' is
NOT a const pointer. As such, they are different types. Yes, 'T*' is
freely convertible to 'const T*' but not the other way around.

At the risk of sounding overly pedantic, in both cases 'this' is a const
pointer. That is, assigning a new value to 'this' isn't legal. The
difference that Daniel is getting at is that in A::foo, 'this' is a
pointer to const A, and in B::foo, 'this' is a pointer to non-const B.
Because of the different const qualifiers, B::foo doesn't override
A::foo. It's not a matter of convertibility, though. If A::foo were
const and B::foo non-const, B::foo still wouldn't override A::foo,
despite the fact that B* is convertible to const A*. An overriding
function has the same cv-qualifiers (const and volatile) as the one it
overrides.
 
R

Riaan

Howard,

I picked up the const on all the functions and fixed everything, but it
still complains that I did not define the pure virtual function. I copied
and past the functions headers to make sure I am not making any other typing
mistakes..but it still gives me the same old error
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

Riaan said:
Howard,

I picked up the const on all the functions and fixed everything, but it
still complains that I did not define the pure virtual function. I copied
and past the functions headers to make sure I am not making any other typing
mistakes..but it still gives me the same old error

-- from Alf P. Steinbach:
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

For the avoidance of doubt: can you declare a variable of type File?

File dummy(0);
Q_EXPORT_PLUGIN2(FileInterface,File);

If `dummy' does not give a compiler error, then look-up the
documentation for Q_EXPORT_PLUGIN2.

Regards, Stephan
 
D

Daniel T.

"Riaan said:
I picked up the const on all the functions and fixed everything, but it
still complains that I did not define the pure virtual function. I copied
and past the functions headers to make sure I am not making any other typing
mistakes..but it still gives me the same old error

Paste the error here and let us look at it. Did you change the const in
the cpp file as well?
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

Daniel said:
Paste the error here and let us look at it. Did you change the const in
the cpp file as well?

AFAIKS this should not matter:
1) the cpp file is not available to the client.
The compiler only needs the header to decide if
an instance of the class `File' is "legal" or not.
2) the cpp file will not compile if the signatures
a class implementation does not match its definition.

Regards, Stephan
 
H

Howard

Riaan said:
Q_EXPORT_PLUGIN2(FileInterface,File);

Please quote the contents of the message you're referring to. The above
line, by itself, tells me nothing, without having to go look at other posts
to see what you're answering.

[Now looking back at the other posts...]

So what is the definition of Q_EXPORT_PLUGIN2? It appears to be a macro
(given it's all in caps). We can't tell you what the error might be without
knowing what the macro expands to.

Can you comment out that line for a moment, and simply instantiate a File
object somewhere?

-Howard
 
R

Riaan

Howard,

Thanks for all the help, but I sorted it out. I had to include another lib
to let the compiler know how to use Q_EXPORT_PLUGIN2 .. it is a QT lib. I
thought it was a pure C++ mistake I made.. but finally they told me is just
the lib that is needed.

--
Riaan Bekker
Howard said:
Riaan said:
Q_EXPORT_PLUGIN2(FileInterface,File);

Please quote the contents of the message you're referring to. The above
line, by itself, tells me nothing, without having to go look at other
posts to see what you're answering.

[Now looking back at the other posts...]

So what is the definition of Q_EXPORT_PLUGIN2? It appears to be a macro
(given it's all in caps). We can't tell you what the error might be
without knowing what the macro expands to.

Can you comment out that line for a moment, and simply instantiate a File
object somewhere?

-Howard
 
R

Riaan

Thanks Stephan and everybody else who helped. It was a lib I had to include
in the bloody thing, QT forgot to mention it in the manuals.
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top