2012-02-01 145 views
0

我正在试图找到一个指南,甚至发现this,但它没有提供答案。 我的问题是如何在构造函数中初始化一个C数组?下面我列举一个我认为正在做的事情的假设例子,但是我不知道它是好的还是错误的,完美的,或者只是出现了问题,并且有办法让它变得更好。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++专家,所以我希望能够收到尽可能多的反馈。如果这是一个重复的问题,也很抱歉,但我真的没有发现任何东西。

+1

你的例子中的数组在哪里?指针不是数组,反之亦然。 – 2012-02-01 19:28:26

+0

你的例子中没有数组,只有指针。 – 2012-02-01 19:29:05

+2

*只是说不。*使用'std :: string'。 – 2012-02-01 19:29:53

回答

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) {} 

如果你的老师坚持认为,你把指针字符的字符串,那么你有你的手一件复杂的事情,因为你必须自己处理管理字符指向的内存,以免最后导致leaking memory。换句话说,你需要实现类似于std::string的东西。

因此,假设你真的需要做到这一点...

  • 每当你使用new你需要一个匹配delete以释放new分配的内存;
  • 你可能想要new被类的构造函数调用;
  • 如果使用适当的析构函数自动存储持续时间类的对象,自动为您完成delete;
  • 该类可以不可复制(例如,通过制作私人拷贝构造函数和复制赋值操作符),或者如果您编写proper copy constructorcopy assignment operator;
  • 您可以使用std::copy算法轻松制作副本,或者如果由于任意原因而受到限制,则可以使用旧的memcpystrcpy函数。

这并不是很简单,但如果你这样做,你将有一个非常方便的类,自动管理你的内存,让你自由地专注于其他问题。

+0

对不起,我不能使用字符串,而我只是添加了缺少的代码部分。对于这种困惑感到抱歉。 – 2012-02-01 19:33:32

+0

@SofiaAlegre:请说出你真正需要做的事情,并提出你的需求的最小,代表性和*完整的例子。这个不完整的“哦,但我不能做ABC我无缘无故分享”不会给你一个很好的答案。仅仅因为*你认为*你在正确的轨道上并没有使这是最好的方法。 – 2012-02-01 19:35:28

+0

基本上我需要通过一个用户数据库创建多个用户帐户对象,这个用户数据库在从[actual]用户(我)收集所有数据后在main方法中调用。我在这个特定的“问题”中的目的是学习如何将值从主方法中的一个char数组传递到另一个特定的新创建的类(a.k.a.用户帐户对象)中。这是否回答你的问题? – 2012-02-01 19:44:06

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 
} 

而在一般情况下,这将是更好的C++风格来使用std::string,让它操心你的记忆:

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); 
} 

否则你复制char *阵列当A的实例死亡时将被泄漏。顺便说一句,你问题中的代码无论如何都会泄漏整个A对象。

+0

谢谢,我也喜欢字符串,但我的教授现在只限制C字符串。 – 2012-02-01 19:37:24

+0

你不应该提到'strdup'而不提及'free'。 – 2012-02-01 19:37:45

+0

好吧,'strdup'是C风格的做法。哦,这让我想起了 - 我忘了添加一个析构函数... @ R.MartinhoFernandes - snap! – Useless 2012-02-01 19:38:48

1

如果您需要使用c字符串(字符数组),您可以使用while循环。请记住,C++中的引号字符串(例如:“test”)是c字符串,但不是字符串。

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; 
} 
1

我认为这是一个练习,你正试图创建自己的字符串类。实际上,我认为这是一个很好的练习。这实际上非常非常艰难。

在任何情况下,一旦您需要了解C++,就是“所有权”。在这种情况下,您的类A将拥有它分配的内存,并将负责稍后删除它。

您需要为new[]分配内存。然后你必须在delete[]之后删除它。后者将在

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; 
} 

我假定创建类通过在字符串作为第二个参数的长度,用户因此类必须聪明地分配额外的角色A的析构函数来完成为空终止符

您的课程尚未完成。您需要处理: - 用户如何阅读字符串。 - 复制你的班级 - 分配你的班级。

请注意,您将得到一个自动生成的副本并分配它将复制并分配您班级的每个成员。问题是你将有2个实例持有相同的指针,他们都会尝试删除它。另外,被分配给的类已经有了一个它需要删除的指针,并且这个指针最终会在空间中丢失(内存泄漏)。

我不会为你回答这个问题,因为你的练习是研究如何处理这种情况。