我有一个简单的类名:
class Name
{ private:
char nameStr[30];
public:
Name(const char * = "");
char * getName() const;
void print() const;
};
我有两个问题,这对我来说有点困难。构造函数应该接受const char *
的参数并将其复制到nameStr数组中。但是,这是我尝试过的并且无法正常工作:
Name::Name(const char * setName)
{
&nameStr = setName;
}
它给出了错误“赋值中的无效左值”。如果我删除nameStr前面的引用,它仍然是错误,说“将'const char *'赋值给'char [30]'”时出现“不兼容的类型”。不太清楚我错过了什么。
另一个问题是存取方法:
char * Name::getName() const
{
return &nameStr[0];
}
我有同样的问题,它错误“从'const char *'无效转换为char *'”我不能为我的生活弄清楚如何让它返回一个指向const char的指针。我一直在寻找利用。找到了关于const的大量信息,但是无法确定如何将它应用到我的情况。任何帮助将不胜感激!
答案 0 :(得分:2)
该行
char nameStr[ 30 ];
而不是(例如)
char * nameStr;
建议您保留整个字符串的“副本”,而不仅仅是指针。所以,
&nameStr = setName;
没有意义。您可以使用类似(但可能不完全正确)
strncpy( nameStr, setName, 30 );
然而,关于第二个问题,为什么要让getName()
方法返回char *
?我看到Name
类封装了一个char
数组,但是如果你公开了char
指针,那么你就会破坏自己的封装。如果确实想要,您可以按const char *
返回return nameStr;
,但更好的方法是避免这种情况。
答案 1 :(得分:1)
当您在类或结构中声明char nameStr[30]
之类的内容时,它会在内部内部创建30个连续字符。 nameStr
的值是指向类中精确位置的常量指针,因此您无法更改它。你必须使用像
strncpy(nanemStr, setName, 30)
。
这会复制字符串的内容并添加一个空终止符。它限制为30个字符,因此您不会溢出缓冲区并破坏宇宙。
答案 2 :(得分:1)
如果您愿意使用std :: string,您可以执行以下操作:
#include <string>
class Name
{ private:
std::string nameStr;
public:
Name(std::string = "");
std::string getName() const;
void print() const;
};
Name::Name(std::string setName)
{
nameStr = setName;
}
std::string Name::getName() const
{
return nameStr;
}
答案 3 :(得分:1)
我建议你使用std :: string,但首先你需要知道指针是如何工作的。
让我们解决您的第一个问题:&nameStr = setName;
此处,nameStr
是一组字符,用于存储您的姓名。 &nameStr
指的是此数组的地址。您不能设置任何类型的变量的地址,这是非法的。例如,&a = &b
(其中a和b是整数)同样是非法的。接下来您尝试了nameStr = setName;
,它表示来自const char* to char[30]
的转换不兼容。你要做的是将一个指针指向另一个指针。这实际上并不复制数据。要复制数据,您需要手动执行此操作,例如:
for (int n=0;(n>0?setName[n-1]!=0:true);n++) { nameStr[n] = setName[n]; }
// The above won't work (or might crash) if the ternary operator evaluates both sides. I don't think it does, but correct me if I'm wrong.
注意,与setName[n-1]
而不是setName[n]
的比较是如此复制NULL字符。
对于您的下一个问题,cannot convert const char* to char*
。获取变量的地址总是会产生一个常量指针,因为不允许更改地址。另请注意,&array[0]
与array
基本相同,因为您取消引用,然后重新引用它,从而使该过程不必要。您需要将getName()函数声明为返回const char*
并在其中返回nameStr
。
关于数组的一个词:数组与其他数据类型一样,只是它们包含多个数据类型,而不是一个。引用数组时,其类型是指向其成员类型的指针。例如,一组int将被视为int*
。指针指向它的第一个元素。这意味着在数组上使用[]将取消引用指向其任何元素的指针。
祝C ++好运!
答案 4 :(得分:1)
为了澄清错误消息所说的内容,语句&nameStr = setName;
字面上说“将nameStr的地址设置为存储在变量setName中的值”。你永远不能改变变量地址的值;这是在定义变量时分配的常量事物。因此,&nameStr
与编译器所说的一样,是一个无效的左值。
答案 5 :(得分:0)
第一个问题 -
However, this is what I have tried and is not working:
Name::Name(const char * setName)
{
&nameStr = setName;
}
It gives me the error "invalid lvalue in assignment".
由于&nameStr
为您提供nameStr
的地址,并且您无法为其指定值,因此在任何赋值语句中都不能将其用作左值。
If I remove the reference in front of nameStr, it still errors, saying
"incompatible types in assignment of 'const char*' to 'char[30]'"
因为nameStr
是一个字符数组,C ++中数组的名称是指向其第一个元素的不可变指针。这意味着您无法更改其指向的位置。
因此,你应该尝试这样的事情 -
strcpy(nameStr, setName);
第二个问题 -
char * Name::getName() const
{
return &nameStr[0];
}
同样,同样的原因 - &nameStr[0]
仍然相当于简单地写nameStr
。
尝试更改功能签名,如 -
const char * Name::getName() const