我正在寻找指南,甚至找到了this,但它没有提供答案。 我的问题是如何在构造函数中初始化C数组?下面我假设一个我想做的假设的例子,但是我不知道它是否可以但是有缺陷,完美,或者只是有一些错误,并且有办法让它变得更好。
class A{
private:
char* a;
int b;
public:
A(char*, int);
}
A::A(char* _a, int _b){
strcpy(a, _a);
b = _b
}
int main(){
A tempA;
char arr[50];
int c = 40;
strcpy(arr,"derp")
tempA = new A(arr,c)
return 0;
}
此刻我没有C ++专家,所以我希望收到尽可能多的反馈意见。如果这是一个重复的问题,也很抱歉,但我在那里找不到任何内容。
答案 0 :(得分:4)
如果要存储字符串,可以存储std::string
:
class A{
private:
std::string a;
int b;
public:
A(std::string const&, int);
}
A::A(std::string const& _a, int _b) : a(_a), b(_b) {}
如果你的教练坚持你将字符指针视为字符串,那么你手上就有一个复杂的问题,因为你必须处理管理字符所指向的内存,以免你最终{{3} }。换句话说,您需要实现类似于std::string
的内容。
所以,假设你真的需要这样做......
new
时,您需要匹配delete
来释放由new
分配的内存; new
; delete
; std::copy
算法轻松制作副本,或者,如果由于任意原因受到限制,您可以使用旧的memcpy
或strcpy
功能。这不是很简单,但如果你这样做,你会有一个非常方便的课程,可以自动管理你的记忆,让你可以专注于其他问题。
答案 1 :(得分:1)
如果需要使用c-string(字符数组),可以使用while循环。还请记住,C ++中的引用字符串(例如:“test”)是c-string而不是字符串。
class A
{
private:
char* a;
int b;
public:
char * get() {return a;}
A(char*, int);
A();
};
A::A(char* _a, int _b)
{
int i=0, lenth=0;
while(_a[i++])
lenth++;
a= new char[lenth+1];
i=0;
while(_a[i])
{
a[i]=_a[i];
i++;
}
a[i]=_a[i];
b = _b;
}
int main()
{
A *tempA;
char arr[50];
int c = 40;
strcpy(arr,"test string");
tempA = new A(arr,c);
cout << tempA->get();
return 0;
}
答案 2 :(得分:1)
我认为这是一个练习,你正在尝试创建自己的字符串类。实际上,我认为这是一个很好的练习。实际上这非常困难。
无论如何,一旦你需要了解C ++的事情就是“所有权”。在这种情况下,您的A类将拥有它分配的内存,并将负责以后删除它。
您需要使用new[]
分配内存。然后您必须稍后使用delete[]
将其删除。后者将在A的析构函数中完成。
class A
{
private:
char* a;
int b;
public:
A(const char*, int);
~A();
};
A::A( const char * a_, int b_ )
: a( new char[b_+1], b( b_ )
{
strncpy( a, a_, b ); // could also use memcpy which would allow embedded nulls,
// in which case you must also add the null terminator yourself.
}
A::~A()
{
delete[] a;
}
我假设创建类的用户将字符串的长度作为第二个参数传递,因此您的类必须是智能的,以便为null终止符分配额外的字符
您的课程尚未完成。你需要处理: - 用户将如何读回字符串。 - 复制你的课程 - 指派你的班级。
请注意,您将获得一个自动生成的副本和分配,它将复制并分配您班级的每个成员。问题是你现在有两个实例持有相同的指针,它们都会尝试删除它。另外,被分配的类已经有一个需要删除的指针,这个指针最终会在空间中丢失(内存泄漏)。
我不打算为你解答,因为你的练习是找出如何处理这种情况。
答案 3 :(得分:0)
strcpy(a, _a)
将无法执行您想要的操作:它假定a
已经指向一些足够大的内存以包含_a
中的内容,而事实并非如此。
这是对当前代码的最小更改:
A::A(char *_a, int _b)
{
a = strdup(_a); // makes a copy
b = _b;
}
更惯用:使用初始化列表,并承诺我们不会修改传入的数组(注意const
):
A::A(char const *_a, int _b)
: a(strdup(_a)), b(_b)
{
// all the work was done above
}
一般来说,使用std::string
会更好的C ++风格,让它为你担心内存:
class A
{
std::string a;
int b;
public:
A(char const *_a, int _b) : a(_a), b(_b) {}
// we can provide two versions, so you can pass in a std::string as well
A(std::string const &_a, int _b) : a(_a), b(_b) {}
};
由于无法使用std::string
进行此分配,因此您无需免费获取内存管理,因此需要编写析构函数:
A::~A()
{
free(a);
}
否则当A的实例死亡时,您复制的char *
数组将被泄露。顺便提一句,你问题中的代码会泄漏整个A
对象。