运算符重载没有显式类型转换

时间:2013-05-05 23:19:42

标签: c++ string class operator-keyword

我尝试为练习目的制作自己的小型String类。我想重载const wchar_t *运算符以返回保存在String对象中的缓冲区,但是当我实际访问该对象时它失败了。它的转换运算符未被调用。只有当我通过(const wchar_t*) mystring

显式地输入对象时,它才有效

编辑:

// CString.h
class CString {
private:
    wchar_t* _string;

    void set(const wchar_t text[]);

public:
    CString();
    CString(const wchar_t text[]);
    CString(const CString& text);

    ~CString();

    operator const wchar_t*() const;
};

// CString.cpp
#include "CString.h"

CString::CString() { set(L""); }
CString::CString(const wchar_t text[]) { set(text); }
CString::~CString() { delete[] _string; }

void CString::set(const wchar_t text[]) {
    delete[] _string;

    _string = new wchar_t[wcslen(text)];
    wcscpy(_string, text);
}

CString::operator const wchar_t*() const {
    return _string;
}

// main.cpp
int main() {
    CString* helloWorld = new CString(L"Test 123");

    MessageBox(NULL, helloWorld, L"", MB_OK);       // This doesn't work
    MessageBox(NULL, (const wchar_t*) helloWorld, L"", MB_OK);  // This works, but I don't explicitly want to use the cast everytime.

    return 0;
}

1 个答案:

答案 0 :(得分:0)

首先,如果您在Windows中工作,CString是来自ATL / MFC的类。为自己的一个类重复使用相同的名称是粗鲁的。

如果不是,您应该为MessageBox提供签名。

我假设你在Windows世界工作。

您的问题是CString*CString不同。您定义了一个运算符,将CString转换为wchar_t const*。毫不奇怪,这不适用于CString*

helloWorld的定义更改为CString helloWorld = CString(L"Test 123"); - 无new,无指针 - 并且您的代码有效。

除此之外,您所做的显式转换导致未定义的行为,因为它将指向对象的指针重新解释为指向字符缓冲区的指针。这是使用C风格的强制转换是一个坏主意的众多原因之一,因为重新解释强制转换和静态强制转换之间的区别需要大量的上下文。要查看错误,请将MessageBox调用更改为MessageBox( NULL, static_cast<const wchar_t*>(helloWorld), L"", MB_OK);显式转换的代码是否运行并打印任何合理的内容?

如果你真的必须将helloWorld放在免费商店中,请在使用它时取消引用它(在隐式和显式转换的情况下)。即,将helloWorld的使用替换为*helloWorld。我建议反对它 - 没有充分的理由将这个特定实例存储在免费商店中。