tags:

views:

930

answers:

2

I simply don't see why this error's popping up.

Widget.cpp: In constructor 'Widget::Widget(Generic, char*, int, int, int, QObject*)':
Widget.cpp:13: error: invalid conversion from 'const char*' to 'char*'

Nowhere do I have a 'const char*' in terms of Widget's constructor.

class Widget: public QObject {
    Q_OBJECT
    Q_PROPERTY(char *col READ getCol WRITE setCol)
    Q_PROPERTY(char *row READ getRow WRITE setRow)
    Generic visitor;
    char *_name;
    char *_widget_base;
    int _row;
    int _col;
    int _type;
    public:
    Widget(Generic visitor, char *name, int row, int col, int type, QObject *parent);
    char* widgetBase() const;
    QString getCol() const;
    void setCol(const QString &col);
    QString getRow() const;
    void setRow(const QString &row);

};

Widget::Widget(Generic v, char *name, int row, int col, int type, 
    QObject *parent = 0 ) {
    visitor = v;
    std::string str(name);
    int pos1 = str.find(":");
    int pos2 = str.rfind(":");
    _widget_base = str.substr(pos1, pos2-pos1).c_str();
    _name = name;
    _row = row;
    _col = col;
    _type = type;
}
+5  A: 

This is a const char * value

str.substr(pos1, pos2-pos1).c_str();
Steve Gilham
+4  A: 

Beyond the compiler error, which has already been answered, your code has some other problems. (At least, assuming the code you posted is near or exactly what you're actually using in your project.)

Even if you change _widget_base to be a const pointer, this line of code is a problem:

_widget_base = str.substr(pos1, pos2-pos1).c_str();

substr returns a temporary string object. The result of c_str() is still owned by that temporary string. And the way that line is written, the temporary string object will be destroyed after the line is executed. Thus the problem is that _widget_base will be left pointing to an area of memory that has been deleted and which may be reused at any time.

You may also have similar problems with _name depending on what you pass into Widget's constructor.

So you could do one of three things with _widget_base and _name

1) Dynamically allocate memory yourself so that it is not managed by any other objects.

std::string temp = str.substr(pos1, pos2-pos1);
_widget_base = new char[temp.length()+1];
strcpy(_widget_base, temp.c_str());

Of course, you would also need to manage the deletion of this memory in your Widget's destructor. And also possibly reallocation if this value could be changed while a Widget exists.

2) Make those member variables character arrays instead of pointers. That way the memory is a permanent part of Widget can doesn't need to be managed. Of course, you'd also have to determine how big is big enough for the arrays.

char _name[a big enough value];
char _widget_base[a big enough value];

and then:

std::string temp = str.substr(pos1, pos2-pos1);
strcpy(_widget_base, temp.c_str());

3) Make those member variables string objects.

std::string _name;
std::string _widget_base;

and then:

_widget_base = str.substr(pos1, pos2-pos1);

This way is the most preferable since it is the most robust and least prone to errors. You have no memory to directly manage and no worry about values that are too large to hold.

TheUndeadFish