表现为局部变量的 C++ 类成员

Posted

技术标签:

【中文标题】表现为局部变量的 C++ 类成员【英文标题】:C++ class member behaving as local variable 【发布时间】:2017-09-23 14:59:49 【问题描述】:

我刚开始用 C++ 编程,我发现了一个尴尬的问题。基本上:

我有一个类,其中成员是包含文件完整路径的char[MAX_LEN]。 我有一个 (char*) 指向文件的名称(没有完整路径)。

在构造这个类的时候,发现(char*)指针其实是指向构造函数内部的一个局部变量,得到错误的结果。

确切地说,类是:

class File_t
  public:
    char        fullPath[1024];
    char*            name;

File_t();  // Default constructor
File_t(const char* fullPath_)
  /*  Copy the input name on fullPath   */
  strncpy(fullPath, fullPath_, sizeof(fullPath));

  /* Auxiliary variable to remove the path */
  char* auxstr=fullPath;
  name = auxstr;

  /* Loop to remove the path  */
  while(1) 
      auxstr = strstr(auxstr,"/");
      if(auxstr)auxstr=auxstr+1; name=auxstr;
      elsebreak;
  

;

例如,主要包括创建几个“File_t”实例并填充几个文件 /some/path/foo1,2,...

int main(int argc, char* argv[])

  const int N = 3;
  File_t CC[N];
  char fileName[100];

  for ( int i = 0; i < N; i++)
    sprintf(fileName,"%s%d","some/path/foo",i);
    CC[i] = File_t(&fileName[0]);
  


  cout << "Summary" << endl;
  for (int i=0; i<N; i++) cout << "File " << CC[i].name << " in " << CC[i].fullPath << endl;


  return 0;

程序输出为:

File foo2 in some/path/foo0
File foo2 in some/path/foo1
File foo2 in some/path/foo2

也就是说,名称指向构造函数的某个局部变量。 Apple、GNU 和 Intel 编译器都有这个问题。

PS:我知道我应该避免在 C++ 中使用 C 风格的字符串,但这只是为了学习 C++ 基础。

【问题讨论】:

永远不要使用strncpy 感谢您的评论。我尝试了 strcpy 并且问题仍然存在。感谢您的回答! 不要使用strstr(),而是使用strrchr()——查找最右边出现的字符(而不是1个字符的字符串)。请注意,您可能需要担心带有斜杠的"/abc/def/ghi//"(带有strrchr()strstr())。不过,总的来说,您似乎找到了人们不建议在 C++ 中使用 C 风格字符串的原因之一。它们很容易被滥用。 像往常一样,对于包含指针的类,问题在于不遵守规则 3。 你的默认构造函数应该让你的类保持一致的状态。最好写成:File_t() name = fullPath; *name = '\0'; 例如。 【参考方案1】:

代码中的问题是赋值运算符(和复制构造函数)损坏。在这一行:

CC[i] = File_t(&fileName[0]);

您构造一个临时的File_t 对象,然后将其分配给CC[i]fullPath 是一个数组,因此所有元素都被复制。这可以。但是name 是一个指针,所以唯一被复制的是指针本身。这是一个问题,因为它仍然指向临时对象的fullPath

在这个语句的最后,临时对象被销毁。现在CC[i].name 是一个无效的指针。

要解决此问题,请定义适当的赋值运算符。它可能会执行以下操作:

strcpy(fullPath, other.fullPath);
name = fullPath + (other.name - other.fullPath);

【讨论】:

【参考方案2】:

Melpomene 给出了答案。没有指明复制过程,指针指向局部变量。

如果添加了复制程序(按照他的建议):

File_t& operator=(const File_t& other)

    strcpy(fullPath, other.fullPath);
    name = &fullPath[0] + (other.name - &other.fullPath[0]);
    return *this;

然后程序运行。

感谢大家的回答!

【讨论】:

以上是关于表现为局部变量的 C++ 类成员的主要内容,如果未能解决你的问题,请参考以下文章

为什么C ++允许类成员函数中的局部变量与成员变量同名?

如何使用 C++ 中的继承函数访问派生类中的局部变量

python 类变量实例(成员)变量局部变量小结

成员变量和局部变量的区别

iOS 局部变量 全局变量 成员变量

成员变量类变量局部变量的区别