再会!
有这样一个问题:需要创建一个String支持获取索引(返回char)并且可以隐式转换为 type的自写类char*。
当一切都井井有条并且我尝试获取索引时,问题就出现了。它给出以下消息(编译器错误):
существует несколько операторов "[]", соответствующих этим операндам:
встроенный оператор "pointer-to-object[integer]"
функцию "String::operator[](size_t index) const"
типы операндов: String [ int ]
据我了解,他看到了两种尝试获取索引下元素的方法:
隐式转换
String到char*它已经在某个索引下获取一个元素使用重载运算符
请告诉我,如何使它在获取索引时明确使用特别重载的索引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 文件是旧项目的回声

好的,让我们试着弄清楚那里发生了什么。通过在指向字符串的指针上声明强制转换运算符,您打开了一个类型安全漏洞。问题是指针默认具有声明的隐式运算符
[]-operator[](const char *, int)。你看到它的主要特点了吗?那里int,你有 size_t。size_t 是“魔法类型”,也就是编译器在里面给自己定义的类型,主要是符合标准。
int它也是一种“魔法类型”。是的,是的,这是最古老的魔法类型之一,即使默认情况下,当它看到没有类型时,编译器也会认为存在int.由于显而易见的原因,很可能在 32 位平台上它将是一个 32 位数字,而在 64 位平台上它将是 64 位(同样,最有可能的是,编译器知道特定平台的功能, 可以自行决定,但在常见平台上很可能是这种情况)。
但是 int 不走运。在 64 位平台上是 32 位。它的大小与 size_t 匹配。并且编译器无法决定选择哪个重载 - 用户定义的运算符 [] 或强制转换为运算符,
char*并且它已经有一个内置的运算符 [] (对我来说,这是一个奇怪的想法,但是标准知道更好)。但在 64 位平台上,不存在这个问题——类型有不同的大小,没有问题。当我们这样写时
name[0u],我们明确指出我们有一个无符号整数,这会自动强制我们使用重载size_t这种过载本身也是危险的。例如,您可以
对我来说,这是超级危险的代码。函数 foo 可以改变里面的一切。
显然,所有这一切都导致它在标准库中被明确表示 -
c_str().