E.Freitas
E.Freitas

Reputation: 532

How to duplicate CString functionality

I have an MFC source file that I need to compile under Qt. This file uses MFC/ATL CString. Specifically it uses a CString as an argument to iostream::open(). I have written a CString class that inherits from QString so that I can use most of QStrings' functionality.

My main concern is that I cannot get my CString implementation to work where iostream::open() is called:

Here is a bit of my class declaration:

    class CString : public QString {
    public:
        CString() : QString() {}
        CString(const QString& other) : QString(other) {}
        CString(const CString& other) : QString(other) {}
        CString(_In_opt_z_ const XCHAR* pszSrc) : QString( pszSrc ) { *this = pszSrc; }
        CString(const char* pszSrc) : QString( pszSrc ) {}
        ...
    }

And, here is a portion of code to use the CString:

ofstream outfile;
CString Path("dump.txt");

outfile.open(Path);

The error is:

no matching function for call to 'std::basic_ofstream >::open(CString&)'

Under 'normal' circumstances, I would simply do something like:

outfile.open(Path.toStdString().c_str());

However, that is not an option. No modification of the original code is authorized. :(

Is there a way to do this, or am I going to have to rebuild the class using the same, rather more complex and lengthy code, that Microsoft uses in cstringt.h?

Thanks

Upvotes: 2

Views: 1153

Answers (6)

alexisdm
alexisdm

Reputation: 29896

You should try a simple:

typedef QByteArray CString;

// And your code should work as expected
ofstream outfile;
CString Path("dump.txt");
outfile.open(Path);

QByteArray has most of QString functions, and the operator const char *.

And if you still want to write a new wrapper class around a QString, thanks to that operator you can use QString::toAscii() instead of the longer QString::toStdString()::c_str().

Upvotes: 0

AJG85
AJG85

Reputation: 16207

Don't attempt to shoehorn MFC code into a Qt environment. Also never inherit from objects that don't have virtual destructors. Which includes QString and most of STL such as std::string

std::ofstream is part of standard C++ and expect a c-style string const char*

Do something like this with QString directly:

ofstream outfile;
QString path("dump.txt");
outfile.open(path.toStdString().c_str());

Or use std::string directly:

ofstream outfile;
std::string path("dump.txt");
outfile.open(path.c_str());

MFC is windows dependent so using it in Qt removes the advantage of cross platform code and doesn't make much sense otherwise as the Qt framework in my opinion is superior to MFC in almost every way.

Upvotes: 1

Baltasarq
Baltasarq

Reputation: 12212

First of all, the correct design for your CString is to wrap QString, instead of inherit from it. After all, you're just rewiring the method calls.

class CString {
public:
    /* ... */
private:
    QString internal;
};

The compiler is complaining about ofstream::open() method not defined for taking a CString argument. This means that the CString was not being taken directly (after all, ofstream is an standard class). You could write a cast in the class so it is converted to char * when required.

class CString {
public:
    /*...*/
    operator const char *()
    {
         return internal.c_str();
    }
private:
    QString internal;
};

This will probably solve the problem. Hope this helps.

Upvotes: 2

Praetorian
Praetorian

Reputation: 109219

Define a typecast operator for your CString class as follows:

operator const char*() { return this->toStdString().c_str(); }

Upvotes: 1

Billy ONeal
Billy ONeal

Reputation: 106609

I have written a CString class that inherits from QString so that I can use most of QStrings' functionality

Do not do this. QString does not have a virtual destructor, and is not intended to be inherited from. In this respect, QString is no different than std::basic_string which is outlined in this other answer.

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272677

According to this, CString has an overloaded operator LPCTSTR, which is how this works without any explicit conversions.

My guess is that if you want to emulate this behaviour, you'll need to provide a similar overload. LPCTSTR is somewhat retarded; so operator const char * is probably better.

Upvotes: 5

Related Questions