【问题标题】:Value of const char* returns empty after construction构造后 const char* 的值返回空
【发布时间】:2021-08-23 09:37:24
【问题描述】:

将此 Vector3 转换为 const char* 在隐式和显式转换中都有效,但在构建时尝试对其进行转换时无效。只有这样 const char* 'v3pchar' 才会返回空白。有什么想法吗?完整代码如下。谢谢!

#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;

struct Vector3 {
    int x, y, z = 0;

    Vector3() {
        cout << "Vector3()" << endl;
    };
    
    Vector3(int X, int Y, int Z) : x(X), y(Y), z(Z) {
        cout << "Vector3(int X, int Y, int Z)" << endl;
    };

    // Focal point here
    operator const char* () {
        cout << "operator const char* called" << endl;
        v3string = to_string(x) + ", " + to_string(y) + ", " + to_string(z);
        v3pchar = v3string.c_str();
        return v3pchar;
    }

private:
    string v3string = "Never even blank";
    const char* v3pchar = "So why does this become blank?";
};

int main() {
    Vector3 v1 = Vector3(1, 2, 3);
    cout << "Vector3 implicit cast to char*: [" << v1 << "]" << endl; // Works

    const char* v2 = v1;
    printf("Vector3 explicit cast to char*: [%s]\n", (const char*)v2); // Works

    cout << "---------------------------------------------" << endl;

    const char* v3 = Vector3(4, 5, 6);
    cout << "Vector3 instantiation cast to char*: [" << v3 << "]" << endl; // Empty

    return 0;
};

【问题讨论】:

  • int x, y, z = 0; 你确定不是int x = 0, y = 0, z = 0;
  • 是的。您所做的只是将z 设置为0,而xy 未初始化,因此如果您调用不带参数的构造函数,xy 将保持未初始化状态。使用未初始化的变量是未定义的行为。 int x = 0, y = 0, z = 0; 将所有值设置为 0 以防止这种情况发生。
  • @josephtaylor xy 的值默认不初始化。如果使用您的第一个构造函数(不带参数),则它们永远不会被赋值。因此,最终可能会得到一个处于“坏”状态的Vector3 对象。使用该对象——也就是说,对它的xy 数据成员做任何事情——将是未定义的行为。如果您使用例如编译器编译,您的编译器可以通知您这些事情。 -Wall 标志。
  • 哦,我什至没有意识到!我以为它会将它们全部设置为 0。也不知道
  • 是的,值得记住的是,在大多数情况下,从函数或类方法返回裸指针是自找麻烦。您必须绝对确定正在处理的任何内容的生命周期。使用智能指针可以消除一些风险。见learncpp.com/cpp-tutorial/…stackoverflow.com/questions/752658/…

标签: c++ casting char-pointer


【解决方案1】:
   v3pchar = v3string.c_str();

c_str() 返回的const char * 指针归其std::string 所有,并且仅在std::string 被修改或被销毁之前有效,以先到者为准。胶囊总结:v3string一旦被修改或销毁,v3pchar就不再有效。

   const char* v3 = Vector3(4, 5, 6);

这会导致以下事件序列:

  1. 创建并构造了一个临时的 Vector3 对象。
  2. 它的operator const char* 方法被调用,它返回一个const char *,该const char * 属于一个内部std::string,它是Vector3 对象的成员。
  3. 返回的const char * 分配给v3
  4. 临时的Vector3 对象连同它的std::string 成员一起被销毁。
  5. 它遵循最初返回的const char * 指针不再有效,因为拥有它的std::string 对象现在已被销毁。

const char * 指针的任何后续使用都会导致未定义的行为。

应该可以修改显示的代码,使用现代 C++ 中的一些功能,这些功能会导致此构造变得不正确(类方法引用限定符),并让您的 C++ 编译器捕获这个常见错误。但这将是另一个问题。至于您观察到结果的原因:由于上述原因,这是未定义的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-04
    • 2012-05-26
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多