构造函数帮助const C-string数组

时间:2010-09-30 05:18:18

标签: c++

我有一个简单的类名:

   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的大量信息,但是无法确定如何将它应用到我的情况。任何帮助将不胜感激!

6 个答案:

答案 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