繁体   English   中英

C ++加运算符无法与const char和其他函数一起使用

[英]C++ plus operator not working with const char and others

你好,我做了一个像string这样的变量存储,这是源

class str
{
private:

    const char * _mystring;

public:

    // Using this function to made new str
    str(const char * _str) { _mystring = _str; }

    // Get the content of this str
    const char * read() { return _mystring; }

    // Get the content in char *
    char * read_c() { return strdup(_mystring); }

    // Operator for equal action with extern const char
    str & operator = (const char * _str) { _mystring = _str; return *this; }

    // Operator for equal action with extern str storage
    str & operator = (str _str) { _mystring = _str.read(); return *this; }

    // Operator for add action
    str operator + (const char * _str) {
        return str(strcat(read_c(), _str));
    }

    // Operator for add action with new str
    str operator + (str & _str) {
        return str(strcat(read_c(), _str.read()));
    }
};

这是我的测试程序

int main() {

    str var1("Var1"); // No problem
    str var2("Var2"); // No problem

    str var3 = var1 + var2;  // No problem
    str var4 = var1 + "tempStr"; // I got runtime error !
    str var5 = "tempStr" + var2; // I got error before compile

    cout << var1.read() << endl;
    cout << var2.read() << endl;
    cout << var3.read() << endl;
    cout << var4.read() << endl;

    return 0;
}

我无法创建类似var3和var4之类的东西的问题是什么(当我想将const char与我的str合并时出现错误...我设置了+运算符,但是当我想合并时出现了问题const char与我的str(不是我的str与const char ...在此操作上,没有问题),但还要等待我在编译并打印var7后得到错误(调试(关闭程序))!

str var3 = "tempTxt0" + "tempTxt1" + "tempTxt2"; // Error
str var4 = "tempTxt3" + var1; // Error

在这些行中,您尝试将2个指针添加到一些静态内存中(换句话说,不会调用您的运算符)

在运算符的左侧, 需要加您的课程

如果您的类的实例为空(仅使用\\0 ,则可以解决您的错误)(您可能已经注意到):

str var4 = str("") + "tempTxt3" + var1; //now it is okay

另外,还要注意strcat为concatening不分配内存,你有这样做realloc自己

对于str var3 = "tempTxt0" + "tempTxt1" + "tempTxt2"; // Error str var3 = "tempTxt0" + "tempTxt1" + "tempTxt2"; // Error

这不起作用,因为编译器会看到以下类型(忽略变量名称): str = const char* + const char* + const char * 将char指针加在一起并不是您想要的。 但是,如果您只有其中一个类型属于class str ,那么它将起作用。 例如, str = str(const char*) + const char* + const char *将调用str::operator+ ,它返回类型为str的新对象,其余对象将以相同的方式进行操作。

对于str var4 = "tempTxt3" + var1; // Error str var4 = "tempTxt3" + var1; // Error

这不起作用,因为您将operator+声明为成员函数。 再次,编译器将看到以下类型(省略变量名): str = const char* + str 没有声明 const char* 作为第一个操作数 ,将str为第二个操作数的operator+ 您有一个成员operator+但该运算符在class str上工作,因此您需要在左侧使用class str 如在str + const char* 将其视为函数调用,因为它恰好是成员函数调用。 与键入str = str.operator+("text") 现在您看到, str = "text".operator+(str)不起作用,因为它不存在

如果您声明了非成员函数str operator+(const char* first, const str& second); ,它将起作用。 编译器将在参数的外部名称空间范围(直到全局范围)(这称为ADL)中寻找与所需条件匹配的运算符。 但是有更好的方法:

声明str operator+(const str& lhs, const str& rhs); 如果您在class str 的命名空间范围内以这种方式声明您的运算符,则编译器将使用第二个参数的类型(即class str )使用ADL( 在Wikipedia上 )并找到该运算符。 然后,编译器可以看到class str具有一个非显式构造函数,该构造函数可以采用const char*str(const char * str) 然后,它可以创建class str的临时对象,并使用您定义的operator+

因此对于您的示例,由于您没有任何名称空间,因此最简单的需要它(注意,我添加了一些const关键字):

class str
{
private:

    const char * _mystring;

public:

    // Using this function to made new str
    str(const char * _str) { _mystring = _str; }

    // Get the content of this str
    const char * read() const { return _mystring; }

    // Get the content in char *
    char * read_c() const { return strdup(_mystring); }

    // Operator for equal action with extern const char
    str & operator = (const char * _str) { _mystring = _str; return *this; }

    // Operator for equal action with extern str storage
    str & operator = (str _str) { _mystring = _str.read(); return *this; }
};

// Operator for add action with new str
str operator+ (const str& lhs, const str& rhs) {
    return str(strcat(lhs.read_c(), rhs.read()));
}

PS您的示例有更多问题。 read_c复制10字节的字符串(可以说),并在其末尾连接更多字节。 这是一个溢出,因为您重复的缓冲区是10个字节。 您必须正确分配和释放内存,但是我想这是另一个问题。 例如

str operator+(const str& lhs, const str& rhs) {
  const std::size_t ls = lhs.size();
  const std::size_t rs = rhs.size();
  char* n = new char[ls + rs + 1];
  std::memcpy(n, lhs.read(), ls);
  std::memcpy(n + ls, rhs.read(), rs);
  n[ls + rs] = '\0';
  return str(n);
}

然后您仍然有什么时候delete的问题。

当您覆盖二进制运算符(例如+ ,左操作数必须是有问题的对象。 出现错误的原因是因为左操作数是一个字符串常量,并且使用了默认的+

您需要为这些运营商接受一个创造友元函数const char *的第一个参数,要么strconst char *第二个参数。

str var4 = var1 +“ tempStr”; //我遇到运行时错误!

在这种情况下,将调用以下operator +重载:

str operator + (const char * _str) {
    return str(strcat(read_c(), _str));
}

您在指针指向不足的缓冲区以容纳当前字符串和_str的指针上调用strcat 最快的解决方案是使用std::string ,否则,您需要分配足够大的缓冲区,并且还要记住要注意其生存期(遵守三个规则)。

str var5 =“ tempStr” + var2; //编译前出现错误

您需要以下签名的全局运算符重载:

str operator + (const char * _str, const str& s);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM