RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1360182
Accepted
DiHASTRO
DiHASTRO
Asked:2022-05-13 00:13:44 +0000 UTC2022-05-13 00:13:44 +0000 UTC 2022-05-13 00:13:44 +0000 UTC

C++ 转换函数和重载的索引接受器冲突

  • 772

再会!

有这样一个问题:需要创建一个String支持获取索引(返回char)并且可以隐式转换为 type的自写类char*。

当一切都井井有条并且我尝试获取索引时,问题就出现了。它给出以下消息(编译器错误):

существует несколько операторов "[]", соответствующих этим операндам:
    встроенный оператор "pointer-to-object[integer]"
    функцию "String::operator[](size_t index) const"

    типы операндов: String [ int ]

据我了解,他看到了两种尝试获取索引下元素的方法:

  1. 隐式转换String到char*它已经在某个索引下获取一个元素

  2. 使用重载运算符

请告诉我,如何使它在获取索引时明确使用特别重载的索引operator[]

这是类代码(不完整,因为类很大,但我向你保证,问题出在这些行中):

字符串.h:

#ifndef CLASS_STRING
#define CLASS_STRING


class String {
public:
    String(const char* str);
    char& operator[](size_t index) const;
    operator char* () const;
private:
    size_t size_;
    size_t capacity_;
    char* pointer_;
};

#endif

字符串.cpp:

#include "String.h"
#include <iostream>

String::String(const char* str)
{
    size_ = 0;
    while (str[size_] != '\0') {
        ++size_;
    }
    capacity_ = size_ + 1;
    pointer_ = new char[capacity_];
    
    for (unsigned int i = 0; i < capacity_; ++i) {
        pointer_[i] = str[i];
    }
}

char& String::operator[](size_t index) const
{
    if (index >= size_) {
        throw std::out_of_range("IndexError: String index out of range");
    }
    return pointer_[index];
}

String::operator char* () const
{
    return pointer_;
}

主.cpp:

#include <iostream>
#include "String.h"

int main() {
    String name = "123";
    std::cout << name[0] << std::endl;
}

先感谢您


PS 上的屏幕截图主要 Pets.cpp 文件是旧项目的回声

有错误的屏幕截图 - 主文件 有错误的屏幕截图 - 头文件

c++
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    KoVadim
    2022-05-13T02:48:15Z2022-05-13T02:48:15Z

    好的,让我们试着弄清楚那里发生了什么。通过在指向字符串的指针上声明强制转换运算符,您打开了一个类型安全漏洞。问题是指针默认具有声明的隐式运算符[]- operator[](const char *, int)。你看到它的主要特点了吗?那里int,你有 size_t。

    size_t 是“魔法类型”,也就是编译器在里面给自己定义的类型,主要是符合标准。

    std::size_t 可以存储理论上可能的任何类型(包括数组)对象的最大大小。

    int它也是一种“魔法类型”。是的,是的,这是最古老的魔法类型之一,即使默认情况下,当它看到没有类型时,编译器也会认为存在int.

    由于显而易见的原因,很可能在 32 位平台上它将是一个 32 位数字,而在 64 位平台上它将是 64 位(同样,最有可能的是,编译器知道特定平台的功能, 可以自行决定,但在常见平台上很可能是这种情况)。

    但是 int 不走运。在 64 位平台上是 32 位。它的大小与 size_t 匹配。并且编译器无法决定选择哪个重载 - 用户定义的运算符 [] 或强制转换为运算符,char*并且它已经有一个内置的运算符 [] (对我来说,这是一个奇怪的想法,但是标准知道更好)。但在 64 位平台上,不存在这个问题——类型有不同的大小,没有问题。

    当我们这样写时name[0u],我们明确指出我们有一个无符号整数,这会自动强制我们使用重载size_t

    这种过载本身也是危险的。例如,您可以

    #include <iostream>
    
    void foo(char* s) {
    }
    
    class String {
        public:
        operator char*() { return nullptr;}
    };
    
    int main()
    {
        String s;
        foo(s);
    }
    

    对我来说,这是超级危险的代码。函数 foo 可以改变里面的一切。

    显然,所有这一切都导致它在标准库中被明确表示 - c_str().

    • 1

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5