我想使用运算符skip_files:
- ^\.git/.*
- ^node_modules/(.*/)?
创建一个程序,以便为一个字符串获取正确的内存量。
new
此示例中的构造函数将普通的#include <iostream>
#include <cstring>
using namespace std;
class String
{
private:
char* str;
public:
String(char* s)
{
int len = strlen(s);
str = new char[len + 1]; // points to a memory
strcpy(str, s);
}
~String()
{
cout << "Deleting";
delete[] str;
}
void display()
{
cout << str << endl;
}
};
int main()
{
String s1 = "who knows";
cout << "s1=";
s1.display();
return 0;
}
字符串作为其参数。它获得空间
用char*
来存储该字符串; new
指向新获得的内存。构造函数
然后使用str
将字符串复制到此新空间中。当然,我也使用了析构函数。
但是,错误是:没有合适的构造函数将const char [10]转换为“ String”。
关于指针,我是一个初学者,我试图理解为什么我的构造函数无法按预期工作。
答案 0 :(得分:0)
如注释中所述,某些编译器会接受您的代码(取决于它们的严格程度)。例如,MSVC
将在禁用"conformance mode"时接受,特别是/Zc:strictStrings
选项。
但是,要完全遵守严格的C ++规则,您需要为String
类提供一个带有const char*
参数的构造函数。只需将该构造函数“重定向”到没有const
关键字的构造函数,并丢弃“ constness”即可轻松实现:
String(const char* cs) : String(const_cast<char*>(cs)) { }
另一种方法(更好的恕我直言,是更好的方法)是将const
限定符添加到现有构造函数的参数中,因为使用const char*
可以很好地完成其中的所有操作(那么您实际上将不需要非const版本):
String(const char* s) {
int len = strlen(s);
str = new char[len + 1]; // points to a memory
strcpy(str, s);
}
没有这些“修正”(或类似的修正)中的一项或多项,您正在将字符串文字(不可变的)的地址传递给带有参数(至少在理论上是这样)的函数(构造函数)指向可以在该函数中更改的数据;因此,严格的编译器在其“权利”内以不允许这样做。由于构造函数不会更改数据,因此将其参数限定为const
应该没有问题。