帮我调试这个 - 来自“const char*”的无效转换到“char*”

发布于 2024-08-06 22:15:16 字数 1130 浏览 5 评论 0原文

我根本不明白为什么会出现这个错误。

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

就 Widget 的构造函数而言,我在任何地方都没有“const char*”。

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;
}

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

也只是曾经 2024-08-13 22:15:16

这是一个 const char *

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

This is a const char * value

str.substr(pos1, pos2-pos1).c_str();
本王不退位尔等都是臣 2024-08-13 22:15:16

除了已经得到解答的编译器错误之外,您的代码还有一些其他问题。 (至少,假设您发布的代码接近或完全是您在项目中实际使用的代码。)

即使您将 _widget_base 更改为 const 指针,这行代码也是一个问题:

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

substr 返回一个临时字符串对象。 c_str() 的结果仍然属于该临时字符串。而该行的写入方式,该行执行后临时字符串对象将被销毁。因此,问题在于 _widget_base 将保留指向已删除且可以随时重用的内存区域。

您可能还会遇到类似的 _name 问题,具体取决于您传递到 Widget 构造函数中的内容。

因此,您可以使用 _widget_base_name 执行以下三件事之一:

1) 自己动态分配内存,使其不被任何其他对象管理。

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

当然,您还需要在 Widget 的析构函数中管理该内存的删除。如果在 Widget 存在时可以更改该值,也可能会重新分配。

2)将这些成员变量设置为字符数组而不是指针。这样内存就成为 Widget 的永久部分,不需要进行管理。当然,您还必须确定数组有多大才足够大。

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

然后:

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

3) 将这些成员变量设为字符串对象。

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

然后:

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

这种方式是最可取的,因为它是最稳健且最不容易出错的。您无需直接管理内存,也不用担心值太大而无法容纳。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文