表现为局部变量的 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++ 类成员的主要内容,如果未能解决你的问题,请参考以下文章